Microsoft ADO.NET Data Services is a quick way to expose a database or entity model as a RESTful web service.  While writing a web service in WCF that handles CRUD operations is relatively straight forward, Data Services has the additional advantage of exposing a sophisticated query language as well as including options for lazy loading.  An obvious application of Data Services is with AJAX applications, such as those built with ExtJS.  Unfortunately, while ExtJS 3.0 now has built-in support for RESTful web services (via DataWriter and DataProxy), it targets conventions that don’t map particularly well to the interface exposed by Data Services. 

The most obvious conflict, and the topic of this post, is in the URI format.  By default, ExtJS assumes REST APIs follow the “Rails-style” convention of passing the Primary Key as a directory reference; e.g., "/Store.svc/Products/22/”.  Instead, Data Services passes the primary key in parenthesis; e.g., “/Store.svc/Products(22)”.  This format change in-and-of-itself is relatively minor; the situation gets a bit more complicated, however, when targeting objects with composite primary keys.  In this case, Data Services expects the primary key values to be parameterized; e.g., “/Store.svc/Cart(UserID=1,ProductID=5)”.  

This is where Data Services' otherwise bloatful metadata property comes in handy.  Not only does this include a serialized format of the primary key, but additionally it's written as a URL.  As such, this issue can easily be overcome by using the __metadata.uri property as the DataReader's idProperty and then overwriting the Ext.data.HttpProxy.buildUrl() method to return this property as the service URL for all REST operations. 

Of course, we only want to change the way ExtJS works for components interfacing with ADO.NET Data Services, so we'll create a new class called DataServicesProxy which inherits from HttpProxy.  Most of this is just out-of-the-box code; the key ingredient is a re-assignment of the service URL to the idProperty.  While we're at it, we're also setting the default format to JSON as a convenience.

Ext.data.DataServicesProxy = function(conn) {
//Set default format to JSON
  var defaults = {
  headers        : {
      'Accept'     : 'application/json'
      }
    }
  Ext.applyIf(conn, defaults);
Ext.data.DataServicesProxy.superclass.constructor.call(this, conn); }; Ext.extend( Ext.data.DataServicesProxy, Ext.data.HttpProxy, { buildUrl : function(action, record) { record = record || null; var url = (this.api[action])? this.api[action].url : this.url; if (!url) { throw new Ext.data.Api.Error('invalid-url', action); } if ( (this.prettyUrls === true || this.restful === true) && record instanceof Ext.data.Record && !record.phantom ) { //This is where the magic happens. url = record.id; } return url; } } );

Then, to instantiate this, you may do something like:

var proxy = new Ext.data.DataServicesProxy({
  url : '/Store.svc/Products',
  });

var reader = new Ext.data.JsonReader(
  { idProperty  : '__metadata.uri',
    root        : 'd'
    },
  [ ... ]
  );

There are, of course, additional challenges that need to be addressed in getting ExtJS and ADO.NET Data Services to work well together; I expect to address some of those in future posts.

Related Posts:

Thursday, September 10, 2009 7:47 AM
Filed Under [ ASP.NET, AJAX, ORM/DAL, ExtJS, ]

Comments

Gravatar
# re: ExtJS with ADO.NET Data Services (Part 1 of 2): RESTful URLs
Posted by Peter Kellner on 4/13/2010 5:03 PM
nice! have you gone further with extjs 3.x and added the api: stuff for updates? I'm on that path myself right now.
Gravatar
# re: ExtJS with ADO.NET Data Services (Part 1 of 2): RESTful URLs
Posted by DotNetWise on 6/10/2010 8:31 PM
Would you please share your final/complete code for Ext.data.DataServicesProxy?

Thanks
Gravatar
# re: ExtJS with ADO.NET Data Services (Part 1 of 2): RESTful URLs
Posted by tham tu on 6/21/2010 3:18 AM
Thank you very much.

Tham tu
Gravatar
# re: ExtJS with ADO.NET Data Services (Part 1 of 2): RESTful URLs
Posted by disaster recovery software on 3/4/2011 7:12 AM
So this code will remove the parentheses? Or will it overwrite and save it as a URL? This is all very helpful.

Post Comment






 

Please add 6 and 4 and type the answer here:
*