Click here to Skip to main content
13,249,087 members (42,571 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

11.2K views
5 bookmarked
Posted 7 Apr 2013

Use jQuery to call ASP.NET Web Service the right way!

, 7 Apr 2013
Rate this:
Please Sign up or sign in to vote.
Use jQuery to call ASP.NET Web Service the right way!

Recently I was revising an application created long time ago which uses AJAX and jQuery extensively, and I found myself doing a common mistake which many articles and forums fall into it. The mistake is Normal Serialization for service methods responds than deserializing the JSON string on the client.

I will describe the mistake using the below example, then we will fix it.

You can download the demo application using the following URL.

I will be using two classes: Courses, and Attendees.

Namespace DataContracts
 Public Class Courses

Property CourseID As Integer
 Property CourseName As String
 Property CourseAttendees As New List(Of Attendees)

End Class

Public Class Attendees

Property FirstName As String
 Property LastName As String

End Class
End Namespace

As the code snippet above, the Courses class will contain two simple properties and another complex property which will hold a list of course attendees.

I will simulate sending attendee complex object from JS to a WebMethod function in the web service, currently the method will return a JSON string, but wait! this is the common mistake because I will manually serialize the complex object to JSON string.  Let’s take a look on the WebMethod GetCourseAttendees.

<WebMethod()> _
 Public Function GetCourseAttendees(ByVal Attendee As DataContracts.Attendees) As String

Dim _Courses As New List(Of DataContracts.Courses)
 Dim _Course1 As New DataContracts.Courses, _Course2 As New DataContracts.Courses

'You can fetch your attendee from the database here.
 With _Course1
 .CourseID = 1
 .CourseName = "jQuery and AJAX"
 .CourseAttendees.Add(New DataContracts.Attendees With {.FirstName = Attendee.FirstName, _
 .LastName = Attendee.LastName})
 End With
 _Courses.Add(_Course1)

With _Course2
 .CourseID = 2
 .CourseName = "Intro to SignalR"
 .CourseAttendees.Add(New DataContracts.Attendees With {.FirstName = Attendee.FirstName, _
 .LastName = Attendee.LastName})
 End With
 _Courses.Add(_Course2)

Dim _JavaScriptSerializer As New Script.Serialization.JavaScriptSerializer

Return _JavaScriptSerializer.Serialize(_Courses)

End Function

The method returns data type as a String (JSON String), if you notice I’m using JavaScriptSerializer object which is responsible for serializing objects and converting it to JSON string, and you really do not need to do this step. Why? Because ASP.NET JSON enabled methods will automatically do this for you and will serialize the responses for objects and collection of objects.

In the current situation what I’m doing is double serializing the responses which means that Courses object will end serialized twice before it is sent to the client. The response in this situation will look like the below, note how there is escape chars before each double quote which means the JSON string is double serialized.

{\"CourseID\":1,\"CourseName\":\"jQuery and AJAX\",\"CourseAttendees\":[{\"
    FirstName\":\"Taiseer\",\"LastName\":\"Joudeh\"}]}

The impact of this mistake will touch three areas:

  1. Adding over head on the server side to serialize the objects returned, we might have huge objects and this will impact server performance.
  2. Increasing the size of the response returned over the network due to the escape chars added.
  3. Most importantly the client will be affected too because the JS will be responsible to convert the JSON string again to JSON object using JSON.Parse or eval as the code snippet below:
$.ajax({
 type: "POST",
 data: JSON.stringify(DTO),
 url: "POSTHandler.asmx/GetCourseAttendees",
 contentType: "application/json; charset=utf-8",
 dataType: "json",
 success: function (result) {

//Using browser native object JSON to parse (Deserialize) the response and convert it to JSON Object.
 var coursesList = JSON.parse(result.d);

//Using eval to parse (Deserialize) the response and convert it to JSON Object.
 var coursesList = eval('(' + result.d + ')');
 }
 });

Fixing this common mistake is pretty easy and straight forward, all you need to do is to depend on the web service to do the serialization step, so the method GetCourseAttendees will look as the below, notice how the return data type now is a list of Courses complex object and I get rid of the unnecessary serialization step using the JavaScriptSerializer.

<WebMethod()> _
 Public Function GetCourseAttendees(ByVal Attendee As DataContracts.Attendees) As List(Of DataContracts.Courses)

Dim _Courses As New List(Of DataContracts.Courses)
 Dim _Course1 As New DataContracts.Courses, _Course2 As New DataContracts.Courses

'You can fetch your attendee from the database here.
 With _Course1
 .CourseID = 1
 .CourseName = "jQuery and AJAX"
 .CourseAttendees.Add(New DataContracts.Attendees With {.FirstName = Attendee.FirstName, _
 .LastName = Attendee.LastName})
 End With
 _Courses.Add(_Course1)

With _Course2
 .CourseID = 2
 .CourseName = "Intro to SignalR"
 .CourseAttendees.Add(New DataContracts.Attendees With {.FirstName = Attendee.FirstName, _
 .LastName = Attendee.LastName})
 End With
 _Courses.Add(_Course2)

Return _Courses

End Function

Now on the client side I will get rid of the unnecessary parsing (deserializing) operation, I will consume the results returned from the WebMethod directly as the code below:

function getAttendees() {

var attendee = {};

attendee.FirstName = "Taiseer";
attendee.LastName = "Joudeh";

// Create data transfer object and send it as JSON string to webservice
var DTO = { 'Attendee': attendee };

$.ajax({
 type: "POST",
 data: JSON.stringify(DTO),
 url: "POSTHandler.asmx/GetCourseAttendees",
 contentType: "application/json; charset=utf-8",
 dataType: "json",
 success: function (result) {
 OngetAttendeesAjaxSucceeded(result);
 },
 error: OngetAttendeesAjaxFailed
 });

function OngetAttendeesAjaxSucceeded(result) {

//You do your for loop on the JSON object or you Use templating technique to present your data.
 var coursesList = result.d;
 var course = "<p>Course Name: " + coursesList[0].CourseName + "</p>"
 var attendeeName = "<p>Attendee Name: " + coursesList[0].CourseAttendees[0].FirstName + "</p>"
 $("#message").html(course + attendeeName);

}

function OngetAttendeesAjaxFailed(xhr, textStatus, error) {

alert("Error occured while getting attendees, Error Code: " + xhr.status + ". Error desc: " + xhr.statusText);
 }
}

Notice how I’m able to pass JSON serialized Attendee object from the client side to the WebMethod and .NET was able to convert it back to a complex object.

Summary

Always remember to depend on the serialization/deserialization provided by the .NET when you consume ASP.NET JSON enabled methods to avoid double serializing responses and the unnecessary overhead on client and server.

Special thanks goes to Dave Ward; reading his blog always enlighten me to use AJAX in the right way.

You can download the demo application using the following URL.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Taiseer Joudeh
Architect Aramex
Jordan Jordan
Taiseer Joudeh has more than 8 years of experience spent in developing and managing different software solutions for finance, transportation, logistics, and e-commerce sectors. He has been deeply involved in .NET development since early framework versions and currently he works on different technologies on the ASP.NET stack with deep passion for Web API, and Microsoft Azure.

Recently Taiseer has been focusing on building Single Page Applications and Hybrid Mobile Solutions using AngularJS.

Taiseer lives in Jordan with his wife and son, works as IT Manager at Aramex, also he is a regular speaker in local events and Dev user groups, he is a avid blogger on http://bitoftech.net, and you can follow him on twitter @tjoudeh

You may also be interested in...

Pro
Pro

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.171114.1 | Last Updated 7 Apr 2013
Article Copyright 2013 by Taiseer Joudeh
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid