Posts Tagged 'REST'

ALT.NET REST Presentation

I just finished my REST presentation at the NYC ALT.NET Meetup. Thanks to all that attended.  Unfortunately I didn’t get through all my samples, but I’m happy to have quality discussion. 

Downloads

I’ve uploaded the sample code and the presentation to my website.  You can use the following links to download them:

Links

As I noted in the resources section of my presentation the following links may be of interest.

RESTful .NET

Above all I’d like to give a lot of credit to Jon Flanders. If it were not for his book this presentation would not have been possible. To anyone who is interested in learning about REST in .NET his book is a must read.

Advertisements

LitWare Training sample application now available on MSDN Code Gallery

The WCF Team at Microsoft just posted their LitWare Training sample application (http://code.msdn.microsoft.com/litwaremashup) on the MSDN Code Gallery website.   The Litware Training application is a sample application using WCF and the WCF REST Starter Kit to build a “Mashup” web site.  LitWare Training is a fictitious training company that maintains registration for technical training courses.  The main selling point for this fictitious company is that it provides a rich, integrated user experience by incorporating multiple services that exist on the internet. 

Litware Training Screenshot

This sample application includes more products and services mashed together than any other application that I’ve seen.  Among the many services and products featured in this application are:

  • ASP.NET
  • Windows Communication Foundation (WCF)
  • WCF REST Starter Kit Preview 2
  • SQL Server 2008
  • Entity Framework
  • Unity
  • jQuery with AJAX
  • Silverlight
  • Virtual Earth
  • Live Search
  • Twitter
  • Facebook
  • Amazon
  • ATOM/RSS Feeds Viewer

At twentysix New York I worked very closely with Kent Brown from Microsoft on this reference application.  Please download the code, take a look, and leave me feedback on this blog if you have any questions.  Additionally, I will be producing a series of screencasts reviewing and demonstrating this application.  Please stay tuned to my blog for updates and links when those screencasts get posted.

Create SendAsync Convenience Extensions for the WCF REST HttpClient to GetAsync and PostAsync

I recently had the pleasure of speaking with some industry icons. We compared some RESTful jQuery code with the new HttpClient code from the WCF Rest Starter Kit Preview 2. The line by line comparison on the code was quite similar (the WCF REST team has done an excellent job with this API, I’m always amazed at how easy it is to use), the main difference was that the jQuery code was transmitting asynchronously. After our conversation, I decided to create these convenience extensions to give developers an API for using lambda expressions to call RESTful services asynchronously in .NET.

Download

In this application I use the jQuery code from my Intro to jQuery presentation and the Live Search WPF Application. The first method I wrote was the GetAsync extension, and after realizing how simple it was I created this entire Extension Library. Additionally, since all the code fit nicely into a single class I’m going to publish the code as a single cs file. As usual, I’m also including the Sample application for download.

HttpAsyncMethodExtensions.cs (12.1KB)

HttpClientExtensions Sample WPF Application (Compressed Zip, 13.1KB)

Code Comparison

The goal of this API was to mimic the jQuery AJAX code that I had previously written. Here is a actual ajax portion of the jQuery code that retrieves some google search results:

$(document).ready(function() {
	$('.getGoogle').click(function(e) {
		//  Prevent the event and Set Loading Message
		e.preventDefault();
		$('.results .noResults').html('Loading...');

		// Generate the google Url
		var googleUri = "http://www.google.com/search?q=" + $('.searchText').val();

		// Send Async GET call
		$.get(googleUri, {}, function(html) {

			// Parse result and create placeholder
			var google = $(html);
			var ul = $('<ul />');

			// find links from results
			$('.g .r .l', google).each(function() {

				// create the list item, generate the list item, and add it to the placeholder
				ul.append($('<li />')
					.append($(this).clone().removeAttr('onmousedown')) // this.clone() clones the google link
				);
			});

			$('.results').append(ul).find('.noResults').remove();
		});
	});
});

Using this jQuery code as a guide I created the usage code first:

private void Search_Click(object sender, RoutedEventArgs e)
{
	// Set Loading Message
	this.Items.Clear();
	this.Items.Add("Loading ...");

	// Generate Google Uri
	const string googleApiUrl = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q={0}";
	var uri = string.Format(googleApiUrl, this.SearchText.Text);

	// Create Client and Send Asynchronous GET
	var client = new HttpClient();
	client.GetAsync(uri, (s, r) =>
	{
		// Clear Loading Message
		this.Items.Clear();

		// Parse Results
		var results = r.Response.Content.ReadAsJsonDataContract<GoogleResults>();

		// Find and add the results
		this.Items.AddRange(results.responseData.results.Cast<object>());
	});
}

I tried to keep the two samples consistent, and as you can see the HttpClient code is 5 lines smaller than its jQuery counterpart. Unfortunately, these samples are not identical implementations. For instance, one client is a web browser and the other is a WPF application. Additionally, both projects have additional code, behind the scenes. But since the goal was to create a similar API I think it works.

HttpClient Extension Methods

What you may not know, is that the HttpClient gains most of its leverage from extension methods. The core functionality of the HttpClient is in its Send method. In the existing API, the Get, Post, Put, Delete methods are extension methods which simple call Send. Using that same concept, here is a GetAsync extension method to the HttpClient:

public static class HttpAsyncMethodExtensions
{
	public static void GetAsync(this HttpClient client, string uri, EventHandler<SendCompletedEventArgs> completed)
	{
		// register callback
		client.SendCompleted += completed;

		// call SendAsync
		var message = new HttpRequestMessage(HttpMethod.GET.ToString(), uri);
		client.SendAsync(message);
	}
}

The HttpClientAsyncExtensions Library, that is downloadable above, contains the full implementation of these extension methods for SendAsync, GetAsync, PostAsync, PutAsync, DeleteAsync, and HeadAsync. There are also a few overloaded helper methods to avoid repeating code.

Conclusion

I think its great that we have the ability to choose between synchronous and asynchronous processing of remote calls. Unfortunately, the amount of code required to perform these tasks is often quite different.

We’ve all seen applications that block the UI thread while executing a long running task synchronously. I’m not sure if this is because of the tools or because of a lack of knowledge around asynchronous programming. Either way, developers often feel that asynchronous programming is difficult.

I’m hoping that these extension methods will show that this doesn’t have to be the case, and that we can actually make remote services calls asynchronously with very little code.

Connecting to Live Search using the HttpClient

Preview 2 of the WCF REST Starter Kit has been posted to CodePlex. Check it out at http://tinyurl.com/wcf-rest-kit2. Included in this latest release of the WCF REST Starter Kit are a great new set of client connection tools that make consumption of RESTful services a breeze.

At the forefront of these client connection tools is the HttpClient. This class allows quick and easy access to download any content from a url. I’ve created a simple WPF Application that demonstrates using the HttpClient and the Live Search API.  For more information on the LiveSearch API or to get your LiveSearch API Key goto http://dev.live.com/getstarted/

Click here to Download the Full Source Code

Windows Live Search WPF Application

This WPF Application consists of a Window with some code-behind,  and a LiveSearch.cs file that was created using the Paste as XML Type feature of the WCF REST Starter Kit.  Before you can serialize your results from the Live Search API you need to run the query in your browser and copy the xml results into your clipboard.  After that you can go into Visual Studio and create a file in your project called LiveSearch.cs and then go to Edit-> Paste as XML Type.  As for the WPF Window it has a Grid with 2 rows and 3 columns.  In the top row is a search textbox and two buttons.  In the second row is a ScrollViewer that contains an ItemsControl. 

The first button does a single threaded search call to the Live Api and sets the ItemsSource of the ItemsControl.  As you can see by the code below its very simple, first we construct the uri, then we call .Get on that uri.  The Get call returns an HttpResponseMessage.  The response message has a number of different chaining methods and extension methods,  we are using the EnsureStatusIsSuccess, which is equivalent to the EnsureStatusIs(HttpStatusCode.OK).  After we call EnsureStatusIsSuccessful (which returns the original message or an exception) we can read the content.  In this case we are reading the content as a xml serialized response of the type created above using the Paste as XML Type feature.

private void Search_Click(object sender, RoutedEventArgs e)
{
      string liveApi = "Your Live Api";
      string uriFormat = "http://api.search.live.net/xml.aspx?AppId={0}&Market=en-US&Query={1}&Sources=web&Web.Count=25";

      using (var client = new HttpClient())
      {
          string uri = string.Format(uriFormat, liveApi, this.SearchText.Text);

          var response = client.Get(uri).EnsureStatusIsSuccessful()
              .Content.ReadAsXmlSerializable<SearchResponse>();

          this.Results.ItemsSource = response.Web.Results;
      }
}

Since its not recommended to run potentially long running operation on the UI thread.  I created a second button to demonstate the Live Search feature using the SendAsync method.  Below is the code for that.

private void SearchAsync_Click(object sender, RoutedEventArgs e)
{
      string liveApi = "Your Live Api";
      string uriFormat = "http://api.search.live.net/xml.aspx?AppId={0}&Market=en-US&Query={1}&Sources=web&Web.Count=25";

      var client = new HttpClient();
      string uri = string.Format(uriFormat, liveApi, this.SearchText.Text);

      client.SendCompleted += client_SendCompleted;
      client.SendAsync(new HttpRequestMessage(HttpMethod.GET.ToString(), uri));
}

void client_SendCompleted(object sender, SendCompletedEventArgs e)
{
      var response = e.Response.EnsureStatusIsSuccessful()
              .Content.ReadAsXmlSerializable<SearchResponse>();

      this.Results.ItemsSource = response.Web.Results;
}

Feel free to download the full demo using the link above, I hope you enjoy it. The new client connect features of the WCF REST Starter Kit create a really simple way of communicating with third party REST services.

jQuery Tab View using AJAX and WCF REST Service

In response to a question on StackOverflow Master Details using jQuery Tabs I wrote little sample app to demonstrate using jQuery Tabs and a WCF REST Service to create a Master Details view of Orders. I decided I’d also reference the solution here and give a little bit of an overview of how the Sample works.

Download

Sample Project: jQuery-AjaxTabView-Sample.zip (194KB)

Default.aspx

The Default page is basically a UI Tab setup with a ListView on the first tab.  The ListView contains a table of Orders with a simple Select link.  Notice that the select button is not an asp hyperlink control.  If you don’t need the extra code-behind or rendering of the user control I avoid them.  But, back to the Default Page.  On the second tab I have to layers one for loading and one for results.  The results tab is preloaded with the default message of Select an order.

The other major function of the page is in the jQuery Scripting, but I’ll get into that later.  First let me explain the service.

WCF Orders Service

With the release of the WCF REST Starter Kit its become very simple to create a service that returns some simple JSON results.   In this sample I have a single service called Service.svc (OrderService might have been a better name, next time…).  The service has a standard WebServiceHost2 Factory definition (which you can view by opening the actual Service.svc file) and a single Service.svc.cs code-behind.  The Service contains two methods one to return all Orders and one to return a single Order’s Details

[ServiceContract]
[ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class OrderDetailsService
{
    [OperationContract]
    [WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]
    public IEnumerable GetOrders()
    {
        // todo: replace with real implementation
        return Order.GetStubData();
    }

    [OperationContract]
    [WebGet(UriTemplate = "{orderId}", ResponseFormat = WebMessageFormat.Json)]
    public List GetOrderDetails(string orderId)
    {
        // todo: replace with real implementation
        var orders = Order.GetStubData();

        // todo: handle bad orderIds
        var order = orders.FirstOrDefault(o => o.OrderId == int.Parse(orderId));

        if (order == null)
            return null;

        return order.Details;
    }
}

You can access http://localhost:{port}/Service.svc to get the Orders as a JSON list, or you can access http://localhost:{port}/Service.svc/1 to get the OrderDetails as a JSON list for Order #1.

jQuery Scripts

Now that you have the WCF Service setup you need to have jquery connect to the service and render the data out when it receives the results.  The basic steps are that occur when the Select button is clicked are:

  1. Call preventDefault to stop the link
  2. Update the Tab2 UI to Loading
  3. Select Tab 2
  4. Parse the OrderId from the Hash of the link
  5. call jQuery $.getJSON(‘Service.svc/{orderId}’, null, function(json) {  } );

When the you return from the getJSON call you need to:

  1. Check to determine that you got valid results
  2. Set error message if necessary
  3. Generate table of results
  4. Loop results creating a row for each result
  5. Reset UI to hide loading and show results

Now on to the actual script that handles this.  Keep in mind that all this code is inside a $(document).ready(), for the full implementation download the sample project.

$('.selectOrder').click(function(e) {
    e.preventDefault();

    //setup loading ui
    $('#tabs').tabs('select', 1);
    $('#tabs-2 .loading').show();
    $('#tabs-2 .results').hide().empty();

    var id = this.hash.replace("#Select_", "")

    $.getJSON("Service.svc/" + id, null, function(details) {
        details.length = details.length ? details.length : 0;
        if (details.length == 0) {
            $('#tabs-2 .results').append('<h3>No Order Details</h3>').show();
        }
        else {
            var table = $('<table />').attr('cellspacing', 0).attr('cellpadding', 4);

            var header = $(<tr />')
                .appendCell("Product")
                .appendCell("Quantity")
                .appendCell("Price")
                .appendCell("Cost")
                .addClass('header');
            table.append(header);

            $.each(details, function() {
                var row = $('<tr />')
                    .appendCell(this.Product)
                    .appendCell(this.Quantity)
                    .appendCell(this.Price)
                    .appendCell(this.Quantity*this.Price);
                table.append(row);
            });

            $('#tabs-2 .results').append(table).show();
        }

        $('#tabs-2 .loading').hide();
    });
});

Conculsion

I hope that you like this sample.  As with any full AJAX solution the real complication comes into play when we start trying to customize the design.  That being said I would recommend putting as much of the design into the css as possible and avoid putting to many styles in the javascript. 

Other things to note, this doesn’t work cross domain, in order to do cross-domain json you need to use jsonp (JSON with Padding).   JSONP can be accomplished through the use of WCF Extensions which is not covered in this article, for more information see this msdn article and this msdn forum post.  jQuery supports jsonp; you would change the getJSON call to $.getJSON(‘Service.svc/1?callback=?’), where callback is the name of the querystring parameter expected by the service, and jquery would recongnize the callback=? and handle all the dirty work for you.  Finally, there is no exception handling in this code.  I just set the length to 0 if I don’t find one.  WCF will actually return the Exception message in the json response.  The next iteration of this project would be to include exception handling in the results callback. 

Happy coding.