and even if you are not an asp.net developer you should.

I have talked a lot of late about WCF Data Services, OData and jQuery and with good reason. These technologies have caused a radical shift in how I develop for the web. So much so that the concept of traditional asp.net data binding is a distant memory now.OData

Now don’t get me wrong, in the early days of asp.net, data binding was a bit of a god send but it also had it’s limitations of being tied pretty heavily to the server.

I now find myself being far more conscious of the end user experience and wanting to push as much processing on to the client as possible and it is the likes of WCF Data Services, OData and jQuery that facilitate this and make it a truly pleasant experience.

If I am boring you with all my talk of OData I make no apologies. It’s simple, elegant and yet powerful. You cannot downplay or underestimate the achievement that the folks at Microsoft have pulled off. Pop on over the odata.org site and check it out. It is well documented.

Now of course jQuery is not a Microsoft effort but they have embraced it and I tip my hat to them for doing so. jQuery is your friend, use it, use it wisely and allow it to open up your world as an asp.net developer.

One of the lessons I have learned over the past decade is not to stick to one technology or technology provider. Sure I have my bias (and that is Microsoft) but I don’t go through life with blinkers on. I attribute that attitude to my good friend Peter in Germany who I remember at the age of 15 (Peter is at least 10 years my senior) telling me at the time to open up my horizons musically as I had Genesis on high rotation. Cut me some slack folks that was back in 1980 Smile

Back to the subject at hand and the powerful combination of all these technologies. Here is the full list which might look daunting to a junior but are the strings you will need in your bow to develop re-world, scalable applications (with a bias for Microsoft. No LAMPs here folks)

  • SQL Server
  • LINQ
  • ASP.NET
  • C#
  • OData Protocol
  • WCF Data Services
  • ADO.NET Entity Framework
  • jQuery
  • HTML
  • CSS

Yes it’s a pretty lengthy list and reads more like a shopping list for potential employers but these are things you should be familiar with. If you are not and you develop for the web then I would encourage you to explore them.

Case Study

So lets take a look at a real world example of tying all of these technologies together.

The sample application below manages a list of products. You can add, edit, delete or disable a product. Now although the sample is hosted in an iframe so you may not notice, there are no traditional post backs going on here at all. All interaction with the server is via ajax calls facilitated by jQuery.

In addition the list is paged and there is no traditional asp.net data binding going on here at all. However, all the data access and paging is being performed on the server. However, rendering the UI and accessing the data is all being handled by javascript using jQuery on the client.

The diagram below shows how all the different parts relate to each other. This follows a traditional client server type application in that everything from the WCF Data Service layer down is on the server and the rest is client side code. The beauty of this is that we very very easily can create a new client application (in Silverlight perhaps) to talk the backend.

image

Advantages

So what are the advantages we are getting out of architecting our application this way.

  • Performance – The application is very responsive to the client. We let the client browser handle all the rendering of the application and we only receive or transmit the data that we need to between the client and server.
  • Standards – The data is returned to the client as json so we can deal with this however we like in a standard way. We are not limited to json, we can also return the data as xml. Try out this link in your browser – http://samples.bondigeek.com/services/PagerService.svc/Products. You should get back the list of products as an RSS feed.
  • Data Modelling made easy– It could not be easier. Create your database tables, configure relationships, drag and drop on to a new ADO.NET Entity Framework Data Model and boom, your done. (See the next point) If our model changes, fine, we just alter the database, refresh the model and we are good to go.
  • Reduction in code – Once we bind our model to our service exposing the data is only a few lines of code. The snippet below is all we need to expose our Products and enable querying them. The QueryInterceptor is an additional feature that I have added that will automatically filter out items marked as deleted when I execute additional queries. (See the next point)

publicclass PagerService : DataService { // This method is called only once to initialize service-wide policies.publicstaticvoid InitializeService(DataServiceConfiguration config) { config.SetEntitySetAccessRule("Products", EntitySetRights.AllRead); config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; } [QueryInterceptor("Products")] public Expressionbool>> OnQueryProducts() { return lo => lo.IsDeleted false; } }

  • Extensibility – One of the beauties of web development is the ability to change things very quickly without the need for recompilation. This solution is no different and also applies to WCF Data Services. We can query the data from the client directly from a url thanks to the OData Protocol. The javascript below does all the data retrieval, paging, sorting and binding of the data. The key points to note here is the url being constructed. When the page is initially rendered this is the URL that gets executed: “/services/PagerService.svc/Products?$orderby=IsDisabled asc, ProductName asc&$skip=0&$top=10&$inlinecount=allpages”. This handles everything for us: The Sorting and the Paging. We are driving this from the client but executing it on the server. No need for any state to be maintained on the server.

function GetProducts() { var skip = "&$skip=" + ((productsPage - 1) * pageSize); var top = "&$top=" + pageSize; $("#products-table tbody").children().remove(); var url = "/services/PagerService.svc/Products?$orderby=IsDisabled asc, " + currentProductSortColumn + " " + currentProductSortDirection + skip + top + "&$inlinecount=allpages"; $.ajax({ type: "GET", url: url, async: false, contentType: "application/json; charset=utf-8", dataType: "json", success: function (msg) { totalProducts = msg.d.__count; products = msg.d.results; var rows = ""; for (var i = 0; i <= products.length - 1; i++) { var className = "odd-row"; if (i % 2 0) { className = "even-row"; } var buttons = ""; if (products[i]["IsDisabled"] false) { buttons += ""; } else { buttons += ""; className += " disabled"; } buttons += ""; rows += "" + products[i]["ProductName"] + "" + products[i]["ProductTitle"] + "" + buttons + ""; } $("#products-table tbody").append(rows); ApplyProductClickHandlers(); if (totalProducts > pageSize) { $("#product-pager").children().remove(); $("#product-pager").append(PagerHtml(totalProducts, productsPage)); $("#product-pager a").click(function () { if ($(this).hasClass("next")) { productsPage = Number(productsPage) + 1; } elseif ($(this).hasClass("previous")) { productsPage = Number(productsPage) - 1; } else { productsPage = $(this).attr("page"); } GetProducts(); }); $("#product-pager").removeClass("hidden"); } else { $("#product-pager").removeClass("hidden"); } }, error: function (xhr) { ShowError(xhr); } }); }

  • Dynamic SQL and LINQ – No need to write another stored procedure (unless you really need to for performance). Once you get your teeth in to the LINQ way of doing things you will rarely go back. The beauty of this is that if your model changes and changes to the extent it would break something you will know at compile time, not the next time someone executes that once in a blue moon stored procedure you created and forgot to update and caused your site to bomb out. Take for instance the example below; If I decided to change a field name or even table then the code would not compile below and I would know straight away.

[WebGet] publicvoid EnableDisableProduct(int productCategoryId) { using (BlogSamplesEntities ctx = new BlogSamplesEntities()) { var item = (from p in ctx.Products where p.ProductId productCategoryId select p).SingleOrDefault(); if (item != null) { item.IsDisabled = !item.IsDisabled; } ctx.SaveChanges(); } }



  • Lean and Clean HTML – Although not a product of the technology we are using, combining all of these technologies together does make it very easy for us to write Lean and Clean mark-up with none of the usual asp.net mechanisms getting in the way. We have full and complete control of our mark-up.

Well I am going to conclude this post for now and I hope I have given you a taste of what makes these technologies so important and why as a Web Developer embracing them will make your life a whole lot easier.

BondiGeek

Full Source Code and Database are here