MSDN Archive Home
Help and FAQs
JSONP and URL-controlled format support for ADO.NET Data Services
All Resource Updates
Change History (all pages)
Notes on the v0.3 update
The last update includes the following tweaks:
Always respond with UTF-8 encoded text to enhance compatibilty with user-agents that indicate different preferences for character encoding
Support both application/json and text/plain for "accept" types to allow for /$count requests
About this JSONP extension for Data Services
JSONP is a common way of making data accessible in client-side mashups even when the requests need to be cross-domain.
While the current version of the ADO.NET Data Services framework does not support this, it's possible to build it on top. There are a couple of ways of doing this. This example shows what's probably the simplest way. There is some downsides to this approach, but overall is the most straightforward path to get there.
The default transport layer for Data Services is WCF, which has a many extensibility points across the stack. For the case of JSONP support, IDispatchMessageInspector comes in handy.
There are two things needed to support JSONP properly:
1. The ability to control the response format. Data Services uses standard HTTP content type negotiation to select what representation of a given resource should be sent to the client (e.g. JSON, Atom). That requires that the caller can set the Accept request header, which is not possible when doing the JSONP trick (which basically just uses <script> tags). We need to add the ability to use the query string in the URL to select format. (e.g. /People(1)/Friends?$orderby=Name&$format=json).
2. A new option to wrap the response in a callback if such callback was provided in the request (also in the query string). For example /People(1)/Friends?$orderby=Name&$format=json&$callback=loaded.
What we'll do is register a message inspector and adjust the request/response when we see these new options coming in.
In order to support the $format=json option we can intercept the message before it gets dispatched to the Astoria runtime, at the IDispatchMessageInspector.AfterReceivedRequest method. If we see the query string option then we'll a) strip it out from the URL so Data Services does not generate an error and b) change the “Accept” header to “application/json”, so the rest of the system just thinks that the client asked for a JSON response in the first place.
Finally, we need to register the interceptor with WCF's dispatchers. For that we create an attribute that implements IServiceBehavior, so we get called during service initialization. When we get called we can register our message interceptor.
The net effect is that if you include this code in your project, you just need to add a single attribute to your Data Service to make it support JSONP:
public class SampleService : DataService<ContactsData>
// your service code here...
Once that's in place you can use JSONP by adding $format and $callback to URLs, for example:
Of course, you can still use all the other Data Services URL options in addition to these.
NOTE about this example
This is just an example. It's just quickly tested, without covering all scenarios. Also, a number of simplifications in the example may need to be addressed if this is used in real applications. For example, the response re-write code assumes that the output encoding is UTF-8 (the default), but the client and server might have negotiated a different character encoding.
Jun 24 2011 at 7:23 PM
, version 6
May 26 2009 at 5:49 PM
From (Line 61): string content = JSONPSupportInspector.encoding.GetString(Convert.FromBase64String(reader.Value));
To (Line 61): string content = JSONPSupportInspector.encoding.GetString(reader.ReadContentAsBase64());
I believe the update above, or similar, ensures that the full JSON string is decoded - more complex entity graphs (using $expand) and larger datasets appeared to miss off "}" and "]" characters, and return an invalid JSON string.
Would love to see an updated and more supported JSONP Data Services sample, as is very useful on the consumer oriented sites I'm working on.
Jun 12 2009 at 5:37 AM
Hey, I am looking for JSONP since last two days, can u update above so that a service supports both XML as well as JSONP format?
Dec 18 2009 at 8:11 PM
andybooth is correct. Line 61 should be altered as he described.
var replyProperties = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name];
Many thanks to pabloc for publishing!
May 7 2010 at 1:50 AM
Thanks for pointing out the glitch in the code. I fixed it and published a new version with the correction in it.
Dec 7 2010 at 3:55 PM
Calling $count (eg http://services.odata.org/OData/OData.svc/Categories(1)/Products/$count) results in an "unsupported media type" exception. I guess this is due to the count being returned in plain text. Haven't figured out how to fix yet ;-). Thnx for the good work.
Dec 7 2010 at 4:09 PM
Changing line 41 from: httpmsg.Headers["Accept"] = "application/json"; to httpmsg.Headers["Accept"] = "application/json,text/plain"; does the trick.
May 17 2011 at 10:43 AM
If you stumbled upon this page and don't have the code for the JSONPSupportBehavior, get it here: http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=DataServicesJSONP&DownloadId=11208
Apr 17 2012 at 7:56 AM
It doesn't work anymore with WCF Data Services 5.0. The following line :
httpmsg.Headers["Accept"] = "application/json, text/plain;q=0.5";
must be changed by
httpmsg.Headers["Accept"] = "application/json;odata=verbose";
May 17 2012 at 2:00 PM
OR you could add both for larger support :
httpmsg.Headers["Accept"] = "application/json, text/plain;q=0.5,application/json;odata=verbose";
Jan 25 2013 at 6:00 PM
NOTE: All of this is moot >= WCF DS 5.1, which supports $format and $callback natively, as well as JSON Light. http://blogs.msdn.com/b/astoriateam/archive/2012/09/26/wcf-data-service-5-1-0-rc2-released.aspx
Sign in to add a comment
Fri Jun 24 2011 at 7:00 AM
More Tags ...
Visual Studio 2008
Visual Studio 2010
Manage Your Profile
MSDN Flash Newsletter
© 2008 Microsoft Corporation. All rights reserved.