Friday, May 4, 2012

RESTful WCF Services with jQuery Mobile (part 1)

One of the most essential techniques in mobile application development is getting data to and from a remote server and displaying it in your application's user interface. As such, it's also one of the more common questions asked in the PhoneGap discussion group. In this post, I'm going to cover the basics of configuring a WCF Service to accept requests using a RESTful interface, returning data in JSON format, and utilize the response to populate the user interface in a jQueryMobile user interface. For this example, the UI will be running from the server with the service, but it could just as easily be running within PhoneGap on a mobile device.

These techniques aren't unique to mobile development. The basic pattern can be applied to any web site. Additionally, while this post covers WCF Services in .NET, other server platforms and technologies would work just as well with jQueryMobile.

The first step in developing a dynamic, AJAX driven user interface is exposing your web service endpoints. Visual Studio 2010 and the Windows Communication Foundation really simplifies this task. It's easy to beat up on Microsoft for their missteps, but WCF is a really solid technology and is the Swiss Army Knife of data plumbing.

Visual Studio 2010 has taken much of the configuration pain out of WCF. It makes the simple things simple, and the complex things possible. Let's start by opening Visual Studio 2010 and creating a new WCF Service Application. Name the project MobileService and the solution MobileSolution, saving the project where the rest of your projects are stored (for convenience sake, I like to store projects in c:\projects, but that's just me.
When the project is created, we start with some stubbed out code to load a class named Service1 using interface IService1 through a service named Service1.svc. Since none of this applies to the solution we want to build, we're going to get rid of it all and start from scratch.
  1. Delete the IService1.cs and Service1.svc files
  2. Remove everything from the Web.config file between <system.serviceModel> and </system.serviceModel>
Right-click on the MobileService project and select Add->New Item. Select AJAX-enabled WCF Service, naming it MobileService.svc
This will add missing elements back into your web.config and create the service file. It also takes care of assigning ASPNetCompatibility. The AspNetCompatibilityRequirements attribute is required for RESTful services. Visual Studio has enabled Web Script in the web.config file. This is a Microsoft-specific method of binding javascript to your WCF method. It won't work with REST, so let's remove it by eliminating the <enableWebScript /> line from the web.config file. While you're at it, rename the behavior to MobileService.webHttpBehavior and add a webHttp element. The name is used to describe what the behavior is for an will be referenced later in the config. The webHttp element specifies that the webHttp binding will be used. This relatively simple binding uses the URI + verb dispatcher to be used. This is what you'll end up with when you're done:
With the configuration straightened out, we'll turn our attention to the body of the service. Start out by eliminating the boiler plate method. For our scenario, we're going to accept a POST and return a list of strings in JSON format. The code for this is shown below. What's important to note is the WebInvoke attribute. This is our connection from the request to the function body. If we were using a verb other than post, we would map the Uri elements to function parameters. Because we're using POST and because this method doesn't require parameters, we're omitting this step. Also note that the message style is wrapped. This allows us to send JSON data to and from the server. At this point, we can fire up Fiddler2 and test this service. Run your application with F5 and copy the url. Switch to fiddler and click on the composer tab. Add the url of your service, the port it's running on, the name of the service, and the UriTemplate from the method. You'll also need to specify that you're working with data in json format by adding Content-type: application/json to the request headers. When you're done, you'll have something like this:
Click the execute button and if you put everything together right, you should see a 200 response in the list of http traffic to the left. Opening that response, you should see something like this:
This shows you the structure of the JSON data returned by your service. Next up - creating a jQueryMobile page that consumes that data.

5 comments:

  1. This is a nice example. Running locally, it was fine during the Fiddler test. When I ran it on a webserver, I needed to add "Content-Length: 0" to the Request Headers in the Fiddler composer window. Thanks for a good tutorial.

    Chuck

    ReplyDelete
  2. Hi!
    I've tried to follow your nice tutorial but I have a problem...When I launch the project by clicking F5 I have the following error: "Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata"...
    May you help me? Thanks

    Paco

    ReplyDelete
  3. If you're trying to run this through visual studio or the WCF test client, you'll see that error because you don't have a metadata endpoint defined.

    You can instead use the Debug Menu to attach to a process. Select "show processes from all users" and "show processes in all sessions" and select W3WP.exe.

    Alternatively, to use visual studio and the WCF Test Client you have to add the metadata endpoint to the element

    ReplyDelete
  4. oops, looks like google filtered out the XML parts of my post.

    <service name="MobileService.MobileService">


    add the following to the element above...
    <endpoint address="mex"
    binding="mexHttpBinding"
    contract="IMetadataExchange" />

    ReplyDelete
  5. When I was on learning curve to WCF, I find it hard but later on realized it is much easier to handle software components. WCF consists of some functional which one can use without worrying about security and reliability.

    ReplyDelete