WebSockets, RIA/JS and WCF Web API at MIX, a whole lotta love for the web

MIX was indeed a busy time for the WCF Team. We delivered several talks, and released several shiny new toys to the community for folks that are building web-based systems.

WebSockets

Craig Kitterman of our Interoperability group, and Paul Batum, whom you might know of from his work on Fluent NHibernate gave a talk: Hot from the Labs: HTML5 WebSockets

In the talk they spoke about new explorations we are doing into supporting WebSockets in the Microsoft Stack. WebSockets is basically sockets for the web, i.e. a way to have a much more responsive in-browser experience. In the talk you’ll learn about the work going on in the W3C/IETF around WebSockets and you’ll see the exploratory work we’ve been doing both at the browser level and on the server to enable a WebSockets experience. I highly recommend this talk, as you’ll see is a pattern for the other talks I mention below.

Here’s a sneak peak of what the coding experience looks like, which I hope you agree is pretty clean.

On the client you have code such as the following:

 conn.onopen = function () {
  state.className = 'success';
  state.innerHTML = 'Socket open';
};
conn.onmessage = function (event) {
  var message = JSON.parse(event.data);
  if (typeof message == 'string') {
    log.innerHTML = '<li class="them">' + 
    message.replace(/[<>&]/g, function (m) 
    { return entities[m]; }) + '</li>' + log.innerHTML; 
  } else {
    connected.innerHTML = message;
  }
};
conn.onclose = function (event) {
  state.className = 'fail';
  state.innerHTML = 'Socket closed';
};

The on the server you have a WebSocket service:

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, 
  ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ChatService : WebSocketsService
{
  ...
  
  public override void OnMessage(string value)
  {
    ChatService.sessions.RelayMessage(this, value);
  }
  public override int GetHashCode()
  {
    return this.id; 
  }
  protected override void OnClose(object sender, EventArgs e)
  {
    ChatService.sessions.Remove(this);
  }
}

You can download the latest bits of the WebSockets work at the HTML 5 labs WebSockets page.

RIA/JS

Brad Olenick of the RIA team delivered a talk: Building Data-centric N-tier Applications with jQuery.

In the talk he unveiled new work the RIA team is doing is to allow consuming RIA services in jQuery! Watch the talk. Brad demonstrates how you can build a rich jQuery front end that dynamically pulls down all of it’s data to the client using RIA. RIA/JS then integrates all the state-tracking/validation richness and such using jQuery validators.  If you are building data-centric jQuery based applications then RIA can take care of a lot of the dirty work for you making your job easier*. This also highlights the value of RIA in that I can reuse my existing domain services now both across Silverlight and Javascript! I know my previous boss (who is deeply missed)  Brad Abrams must be very happy seeing that this is being developed!

*We’re not saying RIA/JS is the panacea for all evils, but it certainly is for some :-)

Here are some of the key scenarios being supported in the first preview.

  1. Query support with sorting, paging, filtering
  2. Changeset submission with two edit modes:
    1. “Implicit Commit” or “write-thru edits” where updates to field values are automatically submitted to your DomainService. This can enable a Netflix.com or Mint.com experience where field changes are submitted to the server as soon as the user tabs out of the field.
    2. “Buffered Changes” mode, where your code must call commitChanges() to submit your changeset to the DomainService. Those that have used the Silverlight client will be most familiar with this mode - a submit button is often used to trigger the commit.
  3. Data change events including collection changes
  4. Client-side change tracking with an entity state API for determining what entities and properties have been edited
  5. Entity data model support that allows you to navigate through associated entity properties and collections
  6. Client-side validation by exposing your server-side validation metadata in jQuery validation format

And here is a snippet of the new RIA/JS syntax. This is a great example of how we are looking to take advantage of awesome OSS solutions for delivering value. It’s about time!

 <script type="text/javascript">
  $(function () {
  var serviceUrl = "/CustomerApp-CustomerService.svc";
  var customers = [];
  var render = function (loadedCustomers) {
    $("#customerForm input[name='CustomerName']").
      val(loadedCustomers[0].CustomerName);
    $("#customerForm").link(loadedCustomers[0]);
  };
  $([customers]).dataSource({
    serviceUrl: serviceUrl,
    queryName: "GetCustomers",
    refresh: render
  }).refresh();
  });
</script>

<div id="customerForm">
    Name: <input type="text" name="CustomerName" />
</div>

After the talk, the RIA team shipped new bits (as in js files) to Codeplex and a new RIA Service jQuery Nuget package! allowing you to start to play with the RIA/JS stuff now.  Go get-em here.

WCF Web API and Preview 4

Continuing along the path web goodness, I delivered a talk: WCF Web APIs: There’s a URI for that.

In the talk I covered the evolution of systems that are now making their capabilities directly available over HTTP including social sites and line of business / enterprise apps. I showed progress we’ve made since PDC on our new WCF addition. The advances have been significant including greatly improving the out of the box experience, enhancing the fidelity you can have when working with HTTP,  improving the configuration story and improving testability.

For example I demonstrated how using our new nuget package, you  quickly you can build a simple service that can return and consume xml, json as well as consume form url encoding content. I then throw an existing jQuery front end on top without having to touch the server side configuration. I then demonstrated how I could easily take my existing service and quickly refactor it to use an IoC container, in this case Autofac, by taking advantage of a new fluent api (which is still a work in progress).

In the second part of my talk, I demonstrated how having rich control of formats/media types can benefit you. This includes showing my resource returning OData, as well a vcard implementation which I use to import contacts directly into gmail. Try that with SOAP, or plain-old XML/JSON, I dare you!

Here’s a snippet of some of the HTTP fidelity I am talking about. Below my service takes advantage of our new HttpResponseMessage<T> and HttpResponseException to return a model AND work with HTTP at the same time.

 [WebGet(UriTemplate = "{id}")]
public HttpResponseMessage<Contact> Get(int id)
{
  var contact = this.repository.Get(id);
  if (contact == null)
  {
    var response = new HttpResponseMessage();
    response.StatusCode = HttpStatusCode.NotFound;
    response.Content = new StringContent("Contact not found");
    throw new HttpResponseException(response);
   }
   var contactResponse = 
     new HttpResponseMessage<Contact>(contact);
   //set it to expire in 5 minutes
   contactResponse.Content.Headers.Expires = 
     new DateTimeOffset(DateTime.Now.AddSeconds(30));
   return contactResponse;
}

The Get method returns a contact and sets caching headers. If the contact is not found however it throws an HttpResponseException passing in an HttpResponseMessage. In this case I am just returning a string, but you have full access to set the response headers/content to whatever you want. Also you might not have caught it, but the id parameter is now passed in as integer. In previous drops as well as in WCF HTTP you had to use a string. Well now we do automatic type conversion. You asked for it, and you got it!

Nuget and Preview 4

After my talk, I am happy to announce that we pushed our next release of WCF Web API (yes drop the s) to Codeplex along with a new set of Nuget packages (webapi.all will get all of ours). You’ll notice a 6th package, WebApi.CrudHttpSample from Steve Michelotti. Rock on Steve! Here’s a link to more on that package.

Preview 4 is loaded with new features much of which is based on your feedback! We’ve been developing them for a while and finally are able to get them out there. All of our apis have been significantly evolved in this release.

Here is a summary of the major things you will find:

  • New message classes HttpResponseMessage<T> / HttpRequestMessage<T> allows accessing headers and using a strongly typed model.

  • Uri parameters can now autocast to primtiive types, i.e. a uri template of "{id}" can map to an integer parameter of id.

  • Matching of parameters is now by type if there is no match on name, ie. HttpRequestMessage req will work.

  • New Operation Handlers which replace processors and dramatically improve the authoring

  • New Formatters for plugging in custom media types

  • New Message Handlers for low level control over HTTP

  • Newer HttpClient

  • Support for Form Url Encoding / Json and Xml out of the box.

  • Support for HTTPs

  • IQueryable support with IQueryable<T> and without requiring attributes

  • Overhauled fluent API for configuration !!!!

  • Unit tests

  • New samples

  • ContactManager is now a fully client based AJAX / JQuery application

    • New ContactManager_Simple illustrates the bare basics.
  • new HelloResource sample

  • Acceptance and Unit tests for some of the samples

I am planning to do some follow up posting detailing all these changes, but this should be enough to keep you guys happy for a while Smile

Go road test this stuff and give us your feedback. We want it, we’re not done yet!