Friday, April 13, 2012

JSON POST with ASP .NET Web API

I have been struggling a bit with porting existing Json calls to the new ASP .NET Web API framework. I actually got the GET request working pretty quickly, but it were the POST (and DELETE en PUT) requests that were giving me headaches. Problem is the current brevity and lack of practical examples for the Web API framework. So here goes a short example of getting a Json POST up and running.

For these examples I used the Visual Studio 2011 beta version.

Let's first start with the GET request. What you need for this is the HttpClient class, which can be found in the System.Net.Http namespace. This class provides methods like GetAsync, PutAsync, DeleteAsync and PostAsync. The 'Async' extensions let you know that you can use the new async and await keywords to get this up and running. A GET requests with the HttpClient consists of only two lines of code.

var client = new HttpClient();
var response = await client.GetAsync("http://some_url/resource_name/resource_id");
response.EnsureSuccessStatusCode();

All of this is contained in a method that has the extra async keyword. I also added the EnsureSuccessStatusCode call to verify my call to the REST service didn't fail. If the call fails the EnsureSuccessStatusCode will throw an exception. So you can easily wrap this piece of code in a try catch block.

So, that was quite easy. The GET call should work immediately.

On to the POST call. I actually want to post an object to our REST service. The previous version of the code I was porting to the Web API used the RestSharp (performs REST calls) and NewtonSoft.Json  (serializes from and to Json) frameworks to perform REST calls (both are available via NuGet). I started out reusing only NewtonSoft.Json, since the HttpClient class removes the need for the RestSharp framework. But is turned out I couldn't get the serialized Json object send to the service in a acceptable format. The service kept giving me 400 Bad Request messages. So I was doing something wrong.

After some searching I found there are a couple of different content class types you can use when performing a PostAsync. I used StringContent up untill then, but I needed a ObjectContent. The HttpRequestMessage class can create one for you. Moreover, the Web API contains its own Json formatters, so the need for the NewtonSoft library became obsolete.

var anObject = new MyObjectType
{
    SomeProperty = "some value"
};

try
{
    var client = new HttpClient(); 
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var requestMessage = new HttpRequestMessage();
    var content = requestMessage.CreateContent<MyObjectType>(
        anObject,
        MediaTypeHeaderValue.Parse("application/json"),
        new MediaTypeFormatter[] { new JsonMediaTypeFormatter() },
        new FormatterSelector());

    var response = await client.PostAsync("http://some_url/resource_name", content);
    response.EnsureSuccessStatusCode();
}
catch (Exception exc)
{
    Console.WriteLine(exc.Message);
}


And there you have it, my first successful Json POST message.

Sunday, March 4, 2012

Adding navigation to WinRT JavaScript

In the previous post we looked at the anatomy of a basic WinRT JavaScript navigation application. In this post we will add 2 additional pages and navigate between them. I will use the same fragment navigation as used in default.html and homePage.html.

First thing I'll do - just to spare me some typing work - is make two copies of homePage.html and call these page2.html and page3.html. Next, I'll alter the default content of homePage.html (there where it says 'content goes here') and replace it with two link tags. I'll add the same content to page2 and 3 as well, so as to easily navigate between all three pages.

<section role="main" aria-label="Main content">
    <p>
        <div>Navigate to: &lt;/div>
        <div>
            <a href="page2.html">Page 2</a>
            <a href="page3.html">Page 3</a>
        </div>
    </p>
</section>

When you try this out, you can actually navigate to page2 and 3. That wasn't too hard to do, now was it. Only downside with this app is, that the back button is not functioning (it stays disabled both on page2 and page3). The appbar as well is not popping up when you click your right mouse button. Also, when you look at it, the contents of pages 2 and 3 are not shown right, they are shown too far to the left. Obviously we need to add some extra code to fix all this.

So I started to play around with this little application, to see what could be done to get it functioning correctly. First thing I did, was add some breakpoints to the default.js file's navigated function. This showed me that, when clicking the page2 or page3 link, the navigated event was not being hit. Apparently, using a simple a tag with an href attribute doesn't trigger navigation. This had to be done some other way then.

For this I added some extra code to the homePage.js file.

function fragmentLoad(elements, options) {
    WinJS.UI.processAll(elements)
        .then(function () {
            // TODO: Initialize the fragment here.
            var page2Nav = document.getElementById('page2Nav');
            if (page2Nav) {
                page2Nav.addEventListener('click', function () {
                    WinJS.Navigation.navigate('/html/page2.html');
                }, false);
            }
        });
}

The fragmentLoad function is called when the homePage gets loaded. When this happens, we get hold of the page2Nav element (I added an id to the link element). If we find this element, we add an eventlistener for its click event. When clicked, we should navigate to page2.html. A similar piece of code can be added to navigate to page3.

After adding this, you will notice that after you click the page2 link, the navigated event in default.js is being hit. That's what we wanted. But wait, as it gets hit, the application doesn't find our back button, its value stays null. That's not right, it should be able to find the back button.

The thing that's wrong here is the fact I added an href to my a tags. If you remove this and let WinJS just handle all of the navigation, you will see the back button is being found. Now, if you land on page2, the back button can be used to navigate back to the homePage. Even the appbar is functioning as expected.

As cool as this is (hey, I can navigate), the downside of using these techniques is that you get an awfully big buy-in into the WinRT way of building apps. When you choose to develop your applications with HTML5 and JavaScript, I think one of the reasons for your choice is portability, the fact that you can take this same code and run it on a different machine with minimal effort. That is why you should think twice when using WinRT functionality. Or, you'd better start writing wrappers for platform specific libraries. But than still ... Hey, I can navigate.

Saturday, March 3, 2012

Navigating with WinRT JavaScript

I am currently playing around with WinRT JavaScript applications. Starting out with a navigation application written from scratch, just to find out how it all fits together. The MSDN library is actually quite scarce when it comes to resources on WinRT. They give you the overall picture of how Metro style apps work, but, for JavaScript applications, the actual information is a bit meager. So I thought it would be nice to dissect a Metro style navigation app and see what code you need to get it up and running. Also beware that the information I will be giving here is based on the first developer preview of Windows 8 and Visual Studio 2011 Express Edition. Things are still very likely to change in the next couple of months.

What I did, was create two Metro style JavaScript applications, one based on a blank project template and one based on the navigation application project template. Let's first see what the navigation application gives us.



When you look at the project of the navigation application, you will see it gives you a couple of predefined html, JavaScript and css files. There are two html files present, a default.html and a homepage.html file. First let's take a look at the homepage.html file. In the head section it includes the JavaScript files you find in the solution, so nothing new or fancy there. In the body there is a div defined with content.

<!-- The content that will be loaded and displayed. -->
<div class="fragment homePage">
    <header role="banner" aria-label="Header content">
        <button disabled class="win-backbutton" aria-label="Back">&lt;/button>
        <div class="titleArea">
            <h1 class="pageTitle win-title">Welcome to NavApp!&lt;/h1>
        </div>
    </header>
    <section role="main" aria-label="Main content">
        <p>Content goes here.&lt;/p>
    </section>
</div>

The main div has a couple of classes defined on it, fragment and homePage. The fragment class we will come back to later on, when we take a look at the JavaScript files of the project. Just remember that it's there on the main div of the homepage.

Within the main div there is a header tag defined. This shows that WinRT JavaScript applications make use of new HTML5 features. The header tag has a role attribute, with a value of banner. There is also a role defined on the section tag a bit further down the homepage, with a value of main. These role attributes are primarily used as selectors in the css and JavaScript files. There is no real functionality associated with them.

The last peculiar attribute values can be found on the button and the h1 tags. Their classes are set to win-backbutton and to win-title respectively. With WinRT JavaScript applications you will find there are a lot of these win-something attribute values. You would think these give you out of the box functionality. Well, they don't. You will find that all magic is really just JavaScript doing it's thing. Those win-something attributes again, are just selectors for the css and JavaScript files. When you run the appication, you will see that the win-backbutton is actually an arrow with a circle around it. That's just plain css:

.win-backbutton::before
{
    font-family: "Segoe UI Symbol";
    content: "\E0D5";
    vertical-align: 50%;
}

So, let's take a look at the default.html page. The header again is just JavaScript and css file includes. The body is more interesting.

<body data-homePage="/html/homePage.html">
    <div id="contentHost">&lt;/div>
    <div id="appbar" data-win-control="WinJS.UI.AppBar" aria-label="Command Bar" data-win-options="{position:'bottom', transient:true, autoHide:0, lightDismiss:false}">
        <div class="win-left">
            <button id="home" class="win-command">
                <span class="win-commandicon win-large">&#xE10F;&lt;/span>&lt;span class="win-label">Home&lt;/span>
            </button>
        </div>
    </div>
</body>

There is a data-homePage attribute on the body tag and it is set to our homePage.htm file. You will also find a contentHost and appbar div. The contentHost makes you suspect that the default.html page is actually the start page of your application and that other html pages will actually be loaded as fragment into it. That is indeed the case here. But then, why, as you run the application, don't I see the appbar that is defined at the bottom. You do get to see all the content of the homePage, but the appbar is nowhere in site. The reason is that, to see the appbar, you need to swipe up, or, if that doesn't work on your device, perform a right mouse click. There's the appbar for you.


So, where does all the magic happen? In the JavaScript files of course. Let's first take a look at the default.js file. There are a couple of functions defined here. Let's not start at the top, but at the bottom.

WinJS.Navigation.addEventListener('navigated', navigated);
WinJS.Application.start();

An eventlistener for the navigated event gets added and the application is started. That's simple, right. Right above these two statements we find the handler for activating the mainwindow.

WinJS.Application.onmainwindowactivated = function (e) {
    if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {
        homePage = document.body.getAttribute('data-homePage');

        document.body.addEventListener('keyup', function (e) {
            if (e.altKey) {
                if (e.keyCode === WinJS.Utilities.Key.leftArrow) {
                    WinJS.Navigation.back();
                }
                else if (e.keyCode === WinJS.Utilities.Key.rightArrow) {
                    WinJS.Navigation.forward();
                }
            }
        }, false);

        WinJS.UI.process(document.getElementById('appbar'))
            .then(function () {
                document.getElementById('home').addEventListener('click', navigateHome, false);
            });

        WinJS.Navigation.navigate(homePage);
    }
}

This code says as much as, when we launch the application, do the following things:
  • Our homepage is set to the attribute value of the data-homePage attribute of the body element.
  • If a user presses the alt key and the left or right button, navigate forward and backward. 
  • Find the appbar and attach a click handler to the home element. The navigateHome function is defined at the top of the JavaScript file and contains pretty straightforward code.
  • And last, but not least, navigate to the homePage.
Right abobe this function, you will find another function definition. 

function navigated(e) {
    WinJS.UI.Fragments.clone(e.detail.location, e.detail.state)
        .then(function (frag) {
            var host = document.getElementById('contentHost');
            host.innerHTML = '';
            host.appendChild(frag);
            document.body.focus();

            var backButton = document.querySelector('header[role=banner] .win-backbutton');
            if (backButton) {
                backButton.addEventListener('click', function () {
                    WinJS.Navigation.back();
                }, false);
                if (WinJS.Navigation.canGoBack) {
                    backButton.removeAttribute('disabled');
                }
                else {
                    backButton.setAttribute('disabled', 'true');
                }
            }
            WinJS.Application.queueEvent({ type: 'fragmentappended', location: e.detail.location, fragment: host, state: e.detail.state });
        });
}

This tells us what happens when we navigate (remember, the previous function actually navigated to the homePage, so this gets called at the start of the application).

  • It clones the current fragment state (I am guessing this remembers where we are coming from and in what state the page is at the moment).
  • And, hey, next bit is some asynchrony. After the cloning is done, a function gets executed for the fragment.
  • It finds the contentHost on the default.html page and appends the fragment to it. There you have masterview (default.html)- detailview (homePage.html) behavior.
  • The backbutton also gets some extra functionality. Based on the fact whether we can go back or not, the button gets disabled or enabled and the click handlers get attached.
  • Last bit is queuing the fact that the fragment got appended, so the WinRT runtime can do its thing.
On the one hand, that's all simple JavaScript code. On the other hand, if you are used to working with the regular .NET languages, this seems like quite some code you need to write for some basic functionality. 

Let's find out, in a next post, what we need to do to navigate to a new page in our application. 

Thursday, February 23, 2012

SvcUtil and Https

A service I need to use for data retrieval recently changed its endpoint definition. The service switched from an HTTP endpoint to an HTTPS endpoint. Since the interface of the service changed as well, I needed to regenerate the interface definitions used to connect to the service.

So, I got out my favourite wsdl tool, svcutil.exe and tried to regenerate the interface definitions as I had done millions of times before. Only to find that the https endpoint was holding me back.


As my command prompt couldn't accept or reject the server's SSL certificate, the wsdl file could not be downloaded.

As a solution for this, you can do the following: Fire up Fiddler and change it's options to decrypt HTTPS traffic. This will add a Fiddler certificate to your certificate store, which is just fine by me.


I did not check the 'Ignore server certificate errors' option, since I still want to know what's going on when some process is going to an HTTPS site.

After setting these options and while Fiddler was silently running in the background, I tried out the svcutil command again. This gave me one more pop up (since I did not check the certificate errors option).



And my classes got generated just fine.

Wednesday, February 22, 2012

Fitnesse, MSpec and SpecFlow

On one of my last projects, I started using Fitnesse tests, primarily to give the business the opportunity to specify their test cases. After playing around with these tests for about 4 days, I, however, threw them out. The main reason for this was the fact that I had to write a whole lot of complementary code to get the Fitnesse tests to run properly.

With Fitnesse, you first need to specify input and output data for your test case. This means edditing a web page with data and writing fixtures in code to process this data. This takes some getting used to and, in my opinion, requires quite some coding. I am also used to refactoring (and renaming) quite a bit during development. But sadly, your Fitnesse test cases don't get refactored, since they live in a separate web application. I also gave myself some extra work by switching over from the slim test runner to the fit test runner. Apparently if you do this, your previously written test fixtures aren't compatible anymore. Something I found very disturbing.

After 4 days of writing Fitnesse tests, I had about 3 test cases finished, I had only a small bit of business code and a huge headache. So, I threw them out.

Instead, I started using MSpec, or Machine Specifications. It is used to write business driven tests, or employ BDD in your code. Now, although MSpec is good for doing BDD, I have noticed it's not because you are using MSpec, that you are doing BDD. You can still write tests the way you used to with NUnit for instance. MSpec is actually just a semantic layer on top of that. But still, it makes it easier to move towards a BDD kinda style of programming.

I must say I really like the way in which you write you MSpec tests, although it does have some downsides and some bits take getting used to as well. I don't think the MSpec tests are always as readable as you would wish. On the one hand, it's nice they make use of lambda expressions a lot, on the other hand, the indentation on those lambdas is just plain awful. It does make you follow an AAA style of testing. Although with MSpec they don't call is Arrange, Act, Assert, but Establish, Because and It. That's just different naming, in essence it's the same thing, right. Another downside is, you can't give these tests to your business users to write them up. It's still developer testing.

This had me looking at SpecFlow, another framework I tried out a couple of weeks later. The test cases you write are more in a business kind of style. They are also easier to write by a business representative (with some additional explanation that is). Once you read the SpecFow documentation you would think you can only test web apps with it in combination with Selenium, but actually, I found it's dead easy to test plain business code with it as well. As with Fitnesse, your SpecFlow tests require you to write some additional code to link your test cases with the actual code, but the good thing is, SpecFlow helps you a lot with this. I used it in combination with my good friend ReSharper and found that this goes very smoothly. If I haven't written any code for a SpecFlow test case, ReSharper suggests a dummy implementation for it which you can copy paste and alter as much as you'd like. That's neat. Only downside I see for now is it's inability to use it for real technical tests. It's not technically impossible, but that's not what it was designed for. Your SpecFlow tests should always be backed up by technical NUnit test cases. That's why it's recommended that you read the Cucumber backgrounder on how to write test cases. The do's and dont's are pretty important here.

I'm actually still playing around with SpecFlow for now. MSpec has already proven it's worth, as did plain NUnit tests. But I think it would actually help a lot to write even more SpecFlow test cases in close communication with the business. I think this is a framework that can deliver.

Tuesday, February 7, 2012

Moving PostSharp to another project

I am currently using PostSharp to add logging and exception handling aspects (to name a few) to an application. PostSharp does this very well and my code has become quite a bit more readable thanks to it. PostSharp actually weaves in extra functionality during your build process. And it can be easily added to an existing project using a nuget package installer.

A recent change in the application however had me refactor out some of the classes I'd added aspects to, to another assembly in the same application. After the refactoring I also added the PostSharp dll to the new project and realized my aspects weren't added/weaved in during the build. This had me thinking, since I did add the PostSharp dll to the new project. After some searching, I found the source of the problem.

Since PostSharp adds extra functionality during your build, you'll need to tell your project (or the C# compile process, that is) to execute this extra PostSharp funcationality. The nuget package actually added this to my original project, but not to any other project in the same solution. So, to solve this, either rerun the nuget package installer on the other project, or, just as easy, add the following xml tag to your csproj file (somewhere at the bottom).

  <Import Project="..\packages\PostSharp.2.1.5.1\tools\PostSharp.targets" />

You get this explanation as well in your projects' properties. You will notice an extra PostSharp tab there, that is either enabled - if PostSharp is doing its' thing - or disabled - if it is not, which was the case for me.

Tuesday, January 10, 2012

SvcUtil and imports

Recently I had to generate a client proxy for a WCF service. As the service was being developed by another team and was running as a local service on their machines, the only thing they could give me to generate my client proxy were the generated wsdl and xsd files of the service. I had no access to the actual service.

So, I started up svcutil.exe and tried to generate the client proxy. This didn't work as expected, however. Since the wsdl file generated by WCF uses imported xsd files. When you run svcutil with access to the actual service, the tool automatically downloads the necessary extra xsd files for you. When, however, you don't have access to the WCF service, you need to specify the extra xsd files in your call to svcutil.

So the following call:

SvcUtil.exe /noconfig the_wsdl_file.xml

Which gives errors on wsdl:portType and wsdl:binding, can be changed to this:

SvcUtil.exe /noconfig the_wsdl_file.xml first_import.xsd second_import.xsd

And that second call works just fine. No errors, my client proxy got nicely generated.

Another must-know about svcutil is that when you want to have your list types generated as a generic list in stead off an array type, you need to use the following extra switch:

/collectionType:System.Collections.Generic.List`1

Beware of the quote there, it's a tricky one. And you do need the entire namespace as well or svcutil won't recognize the type.