Welcome to Professional ASP.NET - Chris Love's Official Blog Sign in | Join | Help

Chris Love's Official ASP.NET Blog

Chris Love's Helpful tips, tricks and pragmatic development knowledge for the ASP.NET world.
Add to Technorati Favorites


ASP Insider Follow Me On Twitter
The query parameter '$format' begins with a system-reserved '$' character but is not recognized

Twitter oData WhiningTuesday morning I was ranting on Twitter, well really whining, about how WCF Data Services does not support JSON format out of the box. Fortunately I was shown the answer in replies to my rant. So I want to share this with you.

First, I made the mistake of learning to work against the oData specification, not WCF Data Services. Despite the marketing feel around oData and WCF Data Services, the latter does not completely implement the oData spec. In particular it does not support JSON out of the box. As a Web/AJAX developer this is sort of a big deal.

Trying to retrieve a WCF Data Service requesting JSON using the $format=json in the querystring results in the following being returned:

This is a screenshot taken in Fiddler. I had to do that because it just gracefully fails making the AJAX call using jQuery.

Yes, I set the Accepts header to application/json and got ATOM back. So finding a solution was very important to me.

Twitter oData WhiningAfter finally determining WCF Data Services does not support JSON out off the box I searched for a solution, one that did not require mush thought to be honest. The first solution I found was by Josh Eistein, where he created an HttpModule to support JSON. But this is WCF and HttpModules just don’t feel right.

Next Mike Flasko pointed me to a WCF JSONP Behavior Pablo Castro has posted on the Microsoft Code Gallery. You can download the sample code that contains the JSON behavior classes you need to add to your service. This is the answer to the problem. Once you add the JSONPSupportBehavior attribute to your service class it now supports the $format=json parameter.

[JSONPSupportBehavior]
public class SampleService : DataService<ContactsData>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
}
}

Now calling the service method using jQuery returns JSON, the easy to digest data format.
 
<script type="text/javascript">
$(document).ready(function () {

var query = "http://localhost.:32006/SampleService.svc/People?$format=json"; //Make sure you adjust your port #

$.ajax({
dataType: "jsonp",
contentType: "application/json",
url: query,
success: callback
});

function callback(response, status, xhr) {
alert(response);
}

});
</script>

Viola!!:

The more I understand how the sausage is actually made at Microsoft the more I understand why this was not included. But then again I have a hard time understanding why in this case. Its a pretty simple thing to implement on the surface at least.

Whatever the reason, this works for now and I am happy. Just wish I did not have to go through the hoops I did to make it work. So download the JSONPSupportBehavior source code and add it to your next WCF Data Service.

Posted: Thursday, June 17, 2010 9:36 AM

by Chris Love
Filed under: , , , ,

Comments

Dave Noderer said:

It worked and I have an approach to xml as well if it turns out I need it which may be the case!
# June 24, 2010 12:50 PM

Nam said:

Thanks Chris, my Data Service can now return JSON. Do you now if your able to return RAW XML, as opposed to atom+xml?
# June 20, 2011 6:44 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS