Leveraging OData end-points in JSON format with JQuery

So I’ve been screwing around with JQuery all weekend in an attempt to make the dynamic-control creation that I have going on in my Silverlight prototype… work without Silverlight!

I’ve been looking for a good way to leverage the Entity-Framework model that I already have in-place so I don’t have to dream up an entire new way of piping my .NET data over to Javascript. It turns out that using WCF Data Services works awesome! (I haven’t tried using EF RIA Services yet, but I bet it will work awesome too.)

Basically, if you want to get data from the O-Data endpoints that both “WCF Data Services” and “EF RIA Services” expose from your E.F. data-model, you simply need to override some of the defaults of the JQuery AJAX() method. Since I wanted my data to be returned in JSON format, and not in ATOM RSS Feed format, I modified the “dataType” parameter of the JQuery AJAX() method as follows :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<script src="Scripts/jquery-1.4.1.min.js" language="javascript" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
 
function addWindowLoadAction(func) {
	if (window.addEventListener) // W3C standard
	window.addEventListener(‘load’, func, false); // CWS **not** ‘onload’
	else if (window.attachEvent) // Microsoft
	window.attachEvent(‘onload’, func);
};
 
window.onload = function () {
	alert(‘I am learning about javascript again!);
};
 
var register2ndButtonClick = function () {
	$(‘#btnTest2′).click(function () {
		$.ajax({
			url: ‘WcfDataService.svc/GenericQuestions?$filter=(GenericQuestionId eq 5)’,
			dataType: ‘json’,
			success: function (data) {
				$(‘.result).html(data);
				alert(‘Load was performed.’);
			}
		});
	});
};
 
addWindowLoadAction(register2ndButtonClick);
</script>
 
<form id="form1" runat="server" name="form1">
	<div>
		<input type="button" id="btnTest" name="btnTest" value="Click">
		<input type="button" id="btnTest2" name="btnTest2" value="Second">
	</div>
</form>

The section in the Javascript that’s cool is inside the registered event handler (looks like an anonymous method… doesn’t it?) for the btnTest2 ‘onClick’ event. There, I use the ‘$’ JQuery object to get a handle on the ‘.ajax’ method. I then pass a JSON data element into the ‘.ajax’ method using directions I found on this website here. http://api.jquery.com/jQuery.ajax/

The really important aspect is that I’m setting the ‘dataType’ parameter to ‘json’. What’s really COOL about how Microsoft implemented their OData-capable WCF data extensions (WCF Data Services & EF RIA Services) is that they enabled the caller to switch between XML ATOM formatted data and JSON formatted data out-of-the-box!

I had previously looked up a way to do JSON formatted data using the URL that’s passed to the OData endpoint exposed by .NET, but then I quickly realized with JQuery, I could control the HTTP ‘Accept’ header information manually by setting the data-type, and therefore elliminate the need for the URL query-string parameter. However, if your interested in how I used a Query-String parameter to change the return data-type for a WCF Data Service from standard ATOM XML to JSON, check out this article for grins. http://code.msdn.microsoft.com/DataServicesJSONP

You may also notice that the URL I passed into the ‘.ajax’ method looks a little strange. ‘WcfDataService.svc/GenericQuestions?$filter=(GenericQuestionId eq 5)’. This is how you perform a WHERE filter on a data-table using the OData endpoints exposed in a facade layer between your Entity Framework model and the browser client. In this case, ‘GenericQuestions’ is one of my Entity names. (It represents a table in the database called ‘GenericQuestion’.) The $filter parameter is how you apply a ‘WHERE’ filter on the table. Here, I’m looking for where the primary key of the table (GenericQuestionId) equals ’5′.

The normal data I would get back from the URL looks something like…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://myBox/MetaHtml/WcfDataService.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">GenericQuestions</title>
  <id>http://myBox/MetaHtml/WcfDataService.svc/GenericQuestions</id>
  <updated>2011-01-31T00:40:01Z</updated>
  <link rel="self" title="GenericQuestions" href="GenericQuestions" />
  <entry>
    <id>http://myBox/MetaHtml/WcfDataService.svc/GenericQuestions(5)</id>
    <title type="text"></title>
    <updated>2011-01-31T00:40:01Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="GenericQuestion" href="GenericQuestions(5)" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/DomainType" type="application/atom+xml;type=entry" title="DomainType" href="GenericQuestions(5)/DomainType" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/FixedDataLookupType" type="application/atom+xml;type=entry" title="FixedDataLookupType" href="GenericQuestions(5)/FixedDataLookupType" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/FixedQuestionLookupType" type="application/atom+xml;type=entry" title="FixedQuestionLookupType" href="GenericQuestions(5)/FixedQuestionLookupType" />
    <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/WorkflowStepQuestions" type="application/atom+xml;type=feed" title="WorkflowStepQuestions" href="GenericQuestions(5)/WorkflowStepQuestions" />
    <category term="CCPortfolioManager.Web.GenericQuestion" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:GenericQuestionId m:type="Edm.Int32">5</d:GenericQuestionId>
        <d:QuestionTypeId m:type="Edm.Int32">13</d:QuestionTypeId>
        <d:DataTypeId m:type="Edm.Int32">3</d:DataTypeId>
        <d:DisplayName>Owner Name</d:DisplayName>
        <d:Description>Name of Owner</d:Description>
        <d:IsActiveFlag m:type="Edm.Boolean">true</d:IsActiveFlag>
        <d:LookupListDomainTypeId m:type="Edm.Int32" m:null="true" />
      </m:properties>
    </content>
  </entry>
</feed>

However, by explicitly setting the AJAX query’s HTTP ‘Accept’ header to ‘application/json’… I am able to receive the following JSON formatted data…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
    "d" : [{
        "__metadata": {
            "uri": "http://mybox/MetaHtml/WcfDataService.svc/GenericQuestions(5)", 
            "type": "CCPortfolioManager.Web.GenericQuestion"
        }, 
        "GenericQuestionId": 5, 
        "QuestionTypeId": 13, 
        "DataTypeId": 3, 
        "DisplayName": "Owner Name", 
        "Description": "Name of Owner", 
        "IsActiveFlag": true, 
        "LookupListDomainTypeId": null, 
        "DomainType": {
            "__deferred": { "uri": "http://mybox/MetaHtml/WcfDataService.svc/GenericQuestions(5)/DomainType" }
        }, 
        "FixedDataLookupType": {
            "__deferred": { "uri": "http://mybox/MetaHtml/WcfDataService.svc/GenericQuestions(5)/FixedDataLookupType" }
        }, 
        "FixedQuestionLookupType": {
            "__deferred": { "uri": "http://mybox/MetaHtml/WcfDataService.svc/GenericQuestions(5)/FixedQuestionLookupType" }
        }, 
        "WorkflowStepQuestions": {
            "__deferred": { "uri": "http://mybox/MetaHtml/WcfDataService.svc/GenericQuestions(5)/WorkflowStepQuestions" }
        }
    }]
}
JQuery JSON data result

JQuery JSON data result

6 Responses to Leveraging OData end-points in JSON format with JQuery

  1. A powerful share, I simply given this onto a colleague who was doing a little analysis on this. And he actually purchased me breakfast because I found it for him.. smile. So let me reword that: Thnx for the treat! But yeah Thnkx for spending the time to debate this, I really feel strongly about it and love reading extra on this topic. If potential, as you change into expertise, would you thoughts updating your blog with extra particulars? It is extremely helpful for me. Huge thumb up for this weblog publish!

    • Chad Stoker says:

      Yes. I’ve actually switched over to leveraging OData endpoints as they are published with RIA Services. That being said, both ways are valid… and the WCF Data Services approach defined here does a better job helping the client-code determine where to find the related data-entities.
      :-)

  2. rtyecript says:

    I really liked the article, and the very cool blog

  3. I relish, result in I found exactly what I used to be looking for. You have ended my 4 day lengthy hunt! God Bless you man. Have a great day. Bye

  4. Hello, Neat post. There is a problem with your website in internet explorer, may check this? IE nonetheless is the marketplace leader and a good component of people will pass over your fantastic writing due to this problem.

  5. We’re a gaggle of volunteers and opening a brand new scheme in our community. Your web site provided us with useful info to work on. You have performed an impressive process and our entire group will likely be grateful to you.

Our Capabilities Include:


Custom Software Development
Enterprise Architecture
Project Management
Systems Analysis
Performance Testing

AND THE LIST GOES ON...

These methods are vital to our work:


Agile Methodology
PMBOK
Test-Driven Development

LEARN WHY...

About CodeSmart, Inc.


CodeSmart has been locally owned and operated in the Olympia, WA area since 2002. We direct, design, develop and deliver full end-to-end information systems using leading edge Microsoft .Net technologies and recommended best practices.

LEARN MORE...