But let’s not stop at OData, lets also give thanks where thanks is due to the likes of WCF Data Services, EntityFramework, jQuery, jqGrid and of course LINQ.

Hallelujah, this is a lethal combination when it comes to web development.

The ease with which a solid solution can be developed using the above technology cannot be underestimated. Not only do you get all the strong typed benefit at the backend but on the front end you can access the WCF Data Services with ease (thanks to OData) and gain all the benefit of asynchronous calls via jQuery.

Read on for more of the gospel

OData

Freed from the shackles of SQL Injection vulnerabilities we can now access data via urls and even compose them in our client side scripts without fear of introducing SQL Injection vulnerabilities. Why? Because we are not composing SQL on the client side. Sure we are sending a dynamic query using QueryString parameters but on the server side this is all being checked for validity, parsed and executed against the database via LINQ. This gives us the freedom to write client side queries like so:

http://domain/services/Organisations?$filter=startswith(Name,'D') eq true

For a full list of query operations check out the Open Data Protocol URI Conventions over here http://www.odata.org/developers/protocols/uri-conventions#FilterSystemQueryOption

WCF Data Services

But wait a second if I can access the data via a url can’t anyone? Sure if you choose to leave your service wide open but even then we can lock it down to read access only with a tiny piece of configuration code:

config.SetEntitySetAccessRule("Organisations", EntitySetRights.AllRead);

In fact you have a whole host of EntitySetRights at your disposal, check em out over here.

EntitySets? what the? Don’t worry we will come to that in just a jiffy.

Security still not good enough? Don’t want anyone to be able to even read data unless they are Authenticated? Not a problem. Implementing this level of control and integrating it with your security model is a cinch. Take for example FormsAuthentication. If you want to restrict access to authenticated users then you just need to check the user is authenticated. I do this with a method that returns a custom User object if the User is authenticated

private OrganisationUser CheckAccess() { OrganisationUser organisationUser = Accounts.GetCurrentUser(); if (organisationUser null) { thrownew System.Security.Authentication.AuthenticationException("You must be logged in to perform that operation."); } else { return organisationUser; } }

The GetCurrentUser method in turn makes a call to System.Web.Security to access the logged on user. If not logged in thenCheckAccess simply throws an AuthenticationException.

MembershipUser user = Membership.GetUser();

And finally to restrict access to our Organisation Entity we just need to add what is called a QueryInterceptor to our service like so:

[QueryInterceptor("Organisations")] public Expressionbool>> OnQueryOrganisations() { OrganisationUser organisationUser = CheckAccess(); return lo => lo.IsDeleted false; }

Now anytime anyone tries to execute a query against the Organisation Entity this interceptor will first check the access the user has and if not authenticated deny access. QueryInterceptors and ChangeInterceptors open up a real opportunity for us. For example,we can restrict what data to return when an OData Query is executed based on the authenticated user account. Or, filter out data that is marked as deleted perhaps.

EntityFramework

I said I would talk about EntitySets a little while ago and this is where the EntityFramework comes in to play which is much improved in .NET 4.0.

EntityFramework is Microsoft ORM technology and seems to be where all the focus is going these days. A big hurrah from me on that one!

So with just a few lines of code we can build an EntityFramework tied to a database allowing us complete OO control of the database. One more line of code and we can expose that Framework via a WCF Data Service:

publicclass MyLibrary : DataService

Now by default all access is locked down. It is up to you as a developer to grant access to just the parts of your EntityFramework you need or want to expose. Each part is an EntitySet. You grant or explicitly deny access via the InitializeService method:

// This method is called only once to initialize service-wide policies.publicstaticvoid InitializeService(DataServiceConfiguration config) { config.SetEntitySetAccessRule("ListOrganisations", EntitySetRights.AllRead); config.SetEntitySetAccessRule("Organisations", EntitySetRights.All); config.SetEntitySetAccessRule("OrganisationUsers", EntitySetRights.All); config.SetEntitySetAccessRule("OrganisationTypes", EntitySetRights.AllRead); config.SetServiceOperationAccessRule("SearchAccounts", ServiceOperationRights.AllRead); config.SetServiceOperationAccessRule("SearchOrganisations", ServiceOperationRights.AllRead); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; }

As you may notice from the above code we are not just restricted to the vanilla Entities, we can also write service operations with more complex logic and LINQ queries on our entities.

So for example we could create a custom search method like so:

[WebGet] public List SearchOrganisations(string searchCriteria, string type)

and then execute that from client side script using the power of OData like so:

var url = "/Services/MyLibrary.svc/SearchOrganisations?searchCriteria='" + searchText + "'&type='" + type + "'";

At the back end a custom query is executed using LINQ using the 2 parameters that are passed in as QueryString arguments.

jQuery

You might be wondering where jQuery fits in to all of this. jQuery just makes it really easy for us to do Asynchronous calls to our WCF Data Services (or synchronous if you prefer) and manage the data that is returned.

So, the process of filling a select list with a list of organisations can be as easy as 1,2,3.

  1. Compose your OData URL and pass this to a Populate method along with the name of the select item we want to populate, formatted in jQuery selection format. In the case below we are calling a custom ServiceOperation on our WCF Data Service but this could easily have been an OData URL.

PopulateOrganisationList("/MyServices/MyLibrary.svc/GetCompanies", "#company-list");

  1. Make a jQuery ajax call to our service passing in our url. On success we want to actually populate our select item so we pass across the returned data and the id of our select object in jQuery selection format.

function PopulateOrganisationList(url, list) { $.ajax({ type: "GET", url: url, contentType: "application/json; charset=utf-8", dataType: "json", success: function (msg) { PopulateList(msg.d, list); }, error: function (xhr) { alert(xhr.status); } }); }

  1. And finally we call our method to actually populate the list using jQuery to find and populate our list:

function PopulateList(results, list) { jQuery(list).length = 0; for (var i = 0; i <= results.length - 1; i++) { jQuery(list).append($("").attr("value", results[i]["ID"]).text(results[i]["Name"])); } }

Wrap Up

Hopefully I have inspired somebody out there who is interested in this technology to get their hands dirty with OData, EntityFramework, WCF Data Services and jQuery. If nothing else I hope I have pointed someone in the right direction who wants to get started with any or all of the above.

It really is a beautiful implementation and a nice pattern to use for web development giving you both power and elegance.

Before I go a quick parting word on jqGrid which is an excellent jQuery grid and mighty powerful to boot. I may dedicate a whole post to it shortly.

BondiGeek