April 26th, 2010 - by Golgotha

In this article we will be looking at a different type of architecture. One in which we utilize jQuery’s ability to easily transfer data (via Ajax and JSON) from the client to the server. We then use ASP.NET and LINQ to SQL to query the database and return a collection of data which gets (automatically) serialized to JSON and sent to the client. The benefits of combining these technologies include: more responsive applications, more processing on the client, less processing on the server and reduced network traffic. Everything runs faster and uses fewer resources.

Still not convinced? Here are some additional benefits of this architecture:

Benefits of the Architecture

  1. Unlike an ASP.NET UpdatePanel we only pass what we need; we only receive what we need. We don’t pass ViewStates, in fact we don’t even have a ViewState. We also don’t pass entire HTML chunks and receive HTML chunks we don’t use. For more on this; read: Why ASP.NET AJAX UpdatePanels are dangerous.
  2. By using jQuery to call the web service directly, we’ve eliminated over 100 KB of JavaScript and three extra HTTP requests that’s included when you use ASP.NET Ajax.
  3. Less dependencies – because all our code is simply xHTML we could switch to a PHP or a Java backend and none of our code for the UI would have to change. That’s right, there are no server-controls; that means no GridViews, no Repeaters, no ListViews, nothing that uses runat server will be found on the page. Not even a ScriptManager.
  4. Usability – We can create RIA interfaces AND maintain usability, giving us the best of both worlds.
  5. Cross-Browser friendly – We use nothing but xHTML code and jQuery which works across browsers.
  6. The entire presentation for the UI is done via CSS. Change the CSS and the entire UI can look different.
  7. We maintain a ‘Separation of Concerns‘ – this means we have 3 distinct and wholly separate code bases. A content or HTML level. A presentation or CSS level and a behavior or JavaScript level. We don’t have code mixed together in a web-page jambalaya.
  8. Switching architectures from Web Forms to MVC is a breeze.

Hopefully you are salivating at these benefits enough to decide to get your feet wet and follow along.

In this article will be leveraging these technologies to build a grid (or what looks like a table). Later on, in future articles, I will then show you how to implement sorting, paging and filtering on the grid. I have divided this article up into four sections: 1. Sever-side code (ASP.NET). 2. HTML 3. jQuery and lastly CSS.

ASP.NET

In this article I will be using LINQ to SQL to query the database and return a collection. LINQ to SQL allows you to model a relational database using .NET classes. You can then query the database using LINQ, as well as update, insert and delete data from it. LINQ to SQL fully supports transactions, views, and stored procedures. If you’re not familiar with LINQ then I will refer you to these articles: Using LINQ to SQL (Part 1) and LINQ to SQL – 5 Minute Overview.

The goal of this article is not to teach you LINQ. But I will say that if you are not using LINQ and you are still using a DataReader or DataSet to access your data then shame on you. Simply put, I believe LINQ is the coolest technology Microsoft has come out with in recent years.

And the best news is, it’s EASY to use. Let’s look at the code:

  1. public class CourseReservations
  2. {
  3.     public long CourseId { get; set; }
  4.     public string Course { get; set; }
  5.     public string Time { get; set; }
  6.     public int Holes { get; set; }
  7.     public int Golfers { get; set; }
  8.     public string FirstName { get; set; }
  9.     public string LastName { get; set; }
  10. }
  11.  
  12. [WebMethod]
  13. public List<CourseReservations> GetGolfCourseReservations()
  14. {
  15.     using (DataContext dc = new DataContext())
  16.     {
  17.         var query = from res in dc.GolfReservations
  18.                     where res.CourseId == 1
  19.                     select new CourseReservations
  20.                     {
  21.                         CourseId = res.CourseId,
  22.                         Course = res.GolfCourse.CourseName,
  23.                         Time = res.DataAndTime.ToShortTimeString(),
  24.                         Holes = res.Holes,
  25.                         Golfers = res.Golfers,
  26.                         FirstName = res.Aspnet_User.GolfUser.FirstName,
  27.                         LastName = res.Aspnet_User.GolfUser.LastName,
  28.                     };
  29.  
  30.         return query.ToList();
  31.     }
  32. }

The first thing we do is create a class called CourseReservations. This class contains all the properties we will need to create our grid on the client. In other words, these will become our columns. The next part is our LINQ statement. This code uses LINQ query syntax to retrieve a sequence of GolfReservations for a given course. Note how the code is querying across the GolfReservations / GolfCourse / Aspnet_User / GolfUser relationships to retrieve all the data we need from our tables, and we didn’t have to write any SQL filled with JOINS to do it.

We then return a list of CourseReservations. What’s important to note is that our list will get automatically serialized to JSON. How fantastic is that? Before we move on, also note the name of our method: GetGolfCourseReservations(). This is what we will call via Ajax using jQuery.

HTML

  1. <ul id="reservationsList" class="stripedList"></ul>

That’s right, just a simple unordered list with an id of “reservationsList” and class of “stripedList”. We don’t use any controls, nothing with runat=”server” will be found on the page. This way we don’t have any ViewState taking up load time, nor do we have Microsoft inserting JavaScript into our page without our consent. Our page, at least on the front-end, is devoid of ASP.NET or any other language. Nothing but pure HTML. If we ever have to port to PHP or JSP we wouldn’t have to change a single thing on the UI side.

jQuery

Let’s look at the jQuery code now. Bit by bit.

javascript
< view plain text >
  1. //Ajax
  2. function SendAjax(urlMethod, jsonData, returnFunction) {
  3.     $.ajax({
  4.         type: "POST",
  5.         contentType: "application/json; charset=utf-8",
  6.         url: urlMethod,
  7.         data: jsonData,
  8.         dataType: "json",
  9.         success: function(msg) {
  10.             // Do something interesting here.
  11.             if (msg != null) {
  12.                 returnFunction(msg);
  13.             }
  14.         },
  15.         error: function(xhr, status, error) {
  16.             // Boil the ASP.NET AJAX error down to JSON.
  17.             var err = eval("(" + xhr.responseText + ")");
  18.  
  19.             // Display the specific error raised by the server
  20.               alert(err.Message);
  21.         }
  22.     });
  23. }

Notice the SendAjax() method’s signature. It takes three parameters, the first urlMethod is the path to the Web Service followed by the name of the Web Method. It should look something like “webservice.asmx/webmethod”. The second parameter jsonData will be exactly that, your JSON data. More on this later. The final parameter returnFunction will be the function you wish to call after the return trip from the server.

The $.ajax() method performs an asynchronous HTTP (Ajax) request. You can read all about it here, but for now, just know it’s the liaison for the client / server relationship; or the Ajax call.

We will use this light, but powerful SendAjax() method over and over again each time we wish to go to the server.

javascript
< view plain text >
  1. //Stripe the rows
  2. function StripeRows(list) {
  3.     $(list).find('li').removeClass('evenRow');
  4.     $(list).find('li:even').addClass('evenRow');
  5. }

This function is simply used to stripe the rows. Every other row will be colored differently in our grid. You pass it a list, it then finds all the list items in that list and removes a class. It then adds a class to all the even list items. The reason why I removeClass() from all list items first is so that if you ever add or remove list items (dynamically) to the grid you don’t get them all messed up colorwise.

javascript
< view plain text >
  1. //This fires when the DOM is ready
  2. //So this starts the ball rolling...
  3. $(document).ready(function() {
  4.     GetGolfCourseReservations();
  5. });

If you are new to jQuery then you need to start by understanding $(document).ready(). You can read all about it here. But the bottom line is that everything inside this method will load as soon as the DOM is loaded and before the page contents are loaded. This is extremely efficient because we don’t have to wait for images or content to load, just the DOM elements. Again, if you are new to jQuery start by understanding the $(document).ready() method.

We are telling it to call the method GetGolfCourseReservations() as soon as browserly possible.

javascript
< view plain text >
  1. function GetGolfCourseReservations()
  2. {
  3.     //Ajax
  4.     var urlMethod = "ws_Reservations.asmx/GetGolfCourseReservations";
  5.     var jsonData = '{}';
  6.     SendAjax(urlMethod, jsonData, ReturnGetGolfCourseReservations);
  7. }
  8. function ReturnGetGolfCourseReservations(msg) {
  9.     var listItems = "";
  10.  
  11.     $.each(msg.d, function(key, val) {
  12.             listItems += "<li>" +
  13.                 "<span class='c1'>" + val.Time + "</span>" +
  14.                 "<span class='c2'>" + val.FirstName + "</span>" +
  15.                 "<span class='c2'>" + val.LastName + "</span>" +
  16.                 "<span class='c3'>" + val.Course + "</span>" +
  17.                 "<span class='c4'>" + val.Holes + "</span>" +
  18.                 "<span class='c4 cLast'>" + val.Golfers + "</span>" +
  19.                 "</li>";
  20.         }
  21.     );
  22.  
  23.     $("#reservationsList").html(listItems);
  24.     StripeRows('#reservationsList');
  25. }

The three lines in the GetGolfCourseReservations() method will become very familiar to you in this methodology. Recall that urlMethod is the path to your web service and your web method. You do remember our .asmx file contains a web method called GetGolfCourseReservations? Good. The next line with jsonData is the JSON that we are passing in. Note that if you are not passing any data, as we are in this case, you must still have the empty curly brackets. Finally, the third line is our call to SendAjax() method. Notice the third parameter: ReturnGetGolfCourseReservations. This is the method to be called on the round trip from the server. Conveniently you will find this function one line down. I always keep to this standard.

In our ReturnGetGolfCourseReservations method we loop through the returned JSON and create our rows or list items. We then drop our list items into our unordered list and lastly call our method to strip the rows.

TIP: Two tools that are indispensable for this methodology are Firebug and this JSON checker. Without Firebug you will not get far. It allows you to see all your Ajax calls, the post, the request and the returned JSON. Get it and learn it.

CSS

Lastly, let’s look at the CSS involved to make our grid look pretty. Do note that we could have used a table instead of a list very easily. It’s your choice.

  1. <style type="text/css">
  2. #reservationsList {width:500px; max-height:600px; background:#fff; overflow:auto;}    
  3.  
  4. /*STRIPE LIST*/    
  5. ul.stripedList {
  6.     margin:0;
  7.     padding:0;
  8.     list-style:none;
  9. }
  10. .stripedList li {
  11.     display:block;
  12.     text-decoration:none;
  13.     color:#333;
  14.     font-family:Arial,Helvetica,sans-serif;
  15.     font-size:12px;
  16.     line-height:20px;
  17.     height:20px;
  18. }
  19. .stripedList li span {
  20.     display:inline-block;
  21.     border-right:1px solid #ccc;
  22.     overflow:hidden;
  23.     text-overflow:ellipsis;
  24.     padding:0 10px;
  25.     height:20px;
  26. }
  27. .stripedList .evenRow {background:#f2f2f2;}
  28.  
  29. .c1 {width:55px;}
  30. .c2 {width:70px;}
  31. .c3 {width:130px;}
  32. .c4 {width:15px;}
  33. .cLast {border:0 !important;}
  34.  
  35. </style>

Most of the CSS is pretty straight forward; we stylize our list-items and use spans as our cells. The classes .c1, .c2 ect. allow us to assign a width to each column.

The Take Away

What I really want you to take away from this article is all the benefits gathered from this methodology. When I build Web-based apps the thing at the front of my mind is speed. It’s all about speed. Nobody likes to wait for anything these days, on the web or off. This is about as fast as you can do things. In addition, we have nice clean code that adheres to the separation-of-concerns. On the front is just good old HTML, probably the first thing you learned when creating websites. On the back-end is our Web Service that does our actionable request: get, save, update and delete. That’s all it does, it knows nothing about the UI, unlike a typical ASP.NET page with its CodeBehind page that is all aware of the UI and talks to it. If we ever had to change over to an Apache server and use PHP we wouldn’t have to change a thing on the front-end, simply our methods on the back-end would change.

We allow our CSS file to control the way the entire application looks. Once again, compare this to many typical ASP.NET apps that use Web Controls and want you to set presentation properties either in the .aspx page or the CodeBehind page. Yuck. Never do that.

Lastly, not only is our code fast and clean, but it’s also lean. When you get good at this methodology there is usually a lot less code. Less code is always a good thing.

33 Responses to “ASP.NET, LINQ, jQuery, JSON, Ajax – Oh my!”

[...] more: ASP.NET, LINQ, jQuery, JSON, Ajax – Oh my! If you enjoyed this article please consider sharing [...]

2 Chris Love

Good job, This is the model I have been preaching for about a year and a half. Its been real freeing for me to adopt this model. You can read through just about every post I have made since Jan 2009 to see how things have progressed. Keep it up!!

3 Eric Coffman

Any chance on getting a working code example of this? I think it would really help put my head around this concept.

4 Eric Coffman

Fantastic article! Thanks for taking the time to write it.

5 Golgotha

@Eric – Yeah, I could give you some code, but since you wouldn’t have the database like mine it wouldn’t do much for you. But, I will get a link up this weekend.

6 Jonesy

Fantastic article, I’ve been thinking of trying this kind of thing for ages, but you get so used to doing things a certain way…

One question: What about Master Pages? Pure HTML is lovely but if you’re building an eCommerce site with thousands of product pages we still need .aspx which sort of defeats the object a little. Would you just integrate as best you can in that instance?

7 Golgotha

@Jonesy – your pages are still .aspx pages. You can still use Master Pages. We simply don’t use server controls like repeaters, gridviews, ect. We just use HTML controls and client-side populate them via jQuery/Ajax.

8 Jose Marmolejos

Excellent approach, tho I rather do away with the entire webforms paradigm and use MVC (MVC 2 now) which, although green, has proven to be a much better alternative than the classic webforms approach.

9 Tim Goyer

An even better solution than using asmx files is to use Page Methods.

In your ASPX code behind files, you can declare static (Shared in VB) methods decorated by the WebMethod attribute in order to return data from the server to your jQuery call in the same way the asmx is used in this sample.

A good article on doing just that is located over on Dave Ward’s blog.

http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/

10 Tim Goyer

That previous comment was for the user expressing concern over the Master templates situation, btw.

Calling web services is a more robust and cleaner way of architecting this as a whole if there are no specific ASP.NET requirements involved..

11 Jonesy

The only thing that concerns me is you’re effectively shifting some of you Data Access Layer to the client. I think the downside is maintenance and a loss of flexibility, upside is speed. I’d love to see an example using traditional classes through ashx or asmx files.

12 Jack Hughes

I’ve recently been dabbling with ASP.NET MVC 2 and would love to see the above done with that if you can. Quite a steep learning curve, I feel like I’m learning about 5 years worth of Microosft stack in the last month. Still, keeps things interesting I guess. ;)

13 Jonesy

I sense a major shift in web development techniques, not unlike in 2000 when .Net was arriving. I see JQuery/AJAX + .Net web services being a must have skillset in the coming years, along with CSS3 to complete the package. Exciting times!

14 Golgotha

@Jack – While I haven’t actually used MVC yet, no job has asked me to, I really LIKE what MVC is doing. That said, this architecture lends itself very well to MVC too. Because once again, the UI side is just xHTML, jQuery, so the backend could be anything, it’s your call: ASP.NET Web Forms, MVC or whatever. And with this approach we are using all Web Services. I don’t even use a CodeBehind page anymore. So while I haven’t used MVC, the transition should be simple.

@Jonesy – Yes, I think this is a paradigm shift. This is my preferred method of coding now. So fast, so clean and so lean.

The initial learning curve can be a little steep if you’re new to jQuery, but then it levels out. Eventually you get disgusted when you have to see a CodeBehind page with ItemDataBound, ItemCreated and FindControl crap going on.

15 Chris Love

@jonesy, You are not moving your data access layer to the client at all. That is still on your server. Your access to it is through your services. You then bind the data as needed to your markup at run-time. So you are not putting the DAL on the client.

16 JT

There is no doubt this is a powerful approach. The big thing that limits its usefulness is the fact that it is not accessible to user agents that don’t support or execute js, including search engine robots and a number of browsers.

This means that this kind of approach is only really applicable where open search availability is not required. There are plenty of places where this is the case, to be sure.

One other note, and this is more of a question: should you use the $.parseJSON() instead of eval for security and performance reasons?

17 Tim Goyer

I would recommend you use $.parseJSON() simply because it will try and use a browser’s native JSON parser if it exists. If not, it will go ahead and eval() it.

18 Dave Ward

@Tim: jQuery 1.4.x uses the browser’s native JSON.parse functionality if it’s available, only falling back to eval() if you’re using an older browser.

19 sbmcn

i like jquery, but i still learn about jquery1.3. Thr book about it in Chinese is little.

20 Naomi

That previous comment was for the user expressing concern over the Master templates situation, btw.

Calling web services is a more robust and cleaner way of architecting this as a whole if there are no specific ASP.NET requirements involved..

21 crusher

There is no doubt this is a powerful approach. The big thing that limits its usefulness is the fact that it is not accessible to user agents that don’t support or execute js, including search engine robots and a number of browsers.

22 Golgotha

@crusher – this is more of a software dev. approach than website dev. approach. When you build software you can say, look you need to have a JavaScript enabled browser for this software to work. You certainly can’t place those demands on a public facing website. Not without some type of ‘Progressive enhancement’ approach.

23 Jay McAnally

Excellent article, but it would be easier for me to follow if I could see/run an example. You have incorporated good snippets but when I try to adapt projects like this, I often find something was overlooked in the discussion.
You mentioned back on April 28th “@Eric – Yeah, I could give you some code, but since you wouldn’t have the database like mine it wouldn’t do much for you. But, I will get a link up this weekend.”
However I can’t find any link. I realize that I’d need to adapt the database to something else (Northwind), and I’ll probably adapt the project to ASP.NET MVC as well, but being able to see your “plumbing” would be a real help.

Thanks,

Jay McAnally

24 Kitchener

You’re appreciated. I read this and was touched to think further about the development on the client side. And with a little lucks, the new book “Closure the definitive guide” helps me giving ASP.NET up. The template from Google Closure is great!

25 Mark

good article,learn more from it.

26 Nick

I’ve been using jQuery ajax and ASP.NET web services, but just got into LINQ and this article helped me manipulate the returned LINQ with jQuery. Thanks…

27 Eric

Just wanted to add to the Thank You list. This got me through a major bottleneck!

28 Jeremy

I really like this. It has great info – my question is, for a functional grid, I need things like sort. In this case I’ve added custom styling so the first list item row is the column headers, but on click, I want to sort without going back to the json data source, instead only sorting one value for the entire grid. Any ideas?

29 Develepoment by zordark - Pearltrees

[...] We maintain a ' Separation of Concerns ' – this means we have 3 distinct and wholly separate code bases. A content or HTML level. A presentation or CSS level and a behavior or JavaScript level. We don't have code mixed together in a web-page jambalaya. Switching architectures from Web Forms to MVC is a breeze. ASP.NET, LINQ, jQuery, JSON, Ajax – Oh my! [...]

30 Ankit

Hey,

That’s a wonderful tutorial for developing web apps in a different approach. However , I have a question that its been 2 yrs u wrote this article. Are there any advancements or change of approach now ? Or should we stick to this one only ?

[...] found the answer below great to get me started. However, I recently stumbled upon Full ASP.NET, LINQ, jQuery, JSON, Ajax Tutorial. It’s just a fantastic and very didactic step-by-step that I want to share with anyone else [...]

32 Basic Simple Asp.net + jQuery + JSON example

[...] found the answer below great to get me started. However, I recently stumbled upon Full ASP.NET, LINQ, jQuery, JSON, Ajax Tutorial. It’s just a fantastic and very didactic step-by-step that I want to share with anyone else [...]

[…] found the answer below great to get me started. However, I recently stumbled upon Full ASP.NET, LINQ, jQuery, JSON, Ajax Tutorial. It’s just a fantastic and very didactic step-by-step that I want to share with anyone else […]

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading


    Warning: fopen(./wp-content/themes/big-blue/my_blogroll.php): failed to open stream: Permission denied in /home/mangeletti/search-this.com/wp-content/themes/big-blue/get_blogroll.php on line 5

    Warning: fread() expects parameter 1 to be resource, boolean given in /home/mangeletti/search-this.com/wp-content/themes/big-blue/get_blogroll.php on line 6

    Warning: fclose() expects parameter 1 to be resource, boolean given in /home/mangeletti/search-this.com/wp-content/themes/big-blue/get_blogroll.php on line 7
  • Smashing Magazine