Click here to Skip to main content
15,889,808 members
Articles / Web Development / HTML
Technical Blog

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

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
7 Apr 2013CPOL3 min read 14.6K   5  
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.

VB
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.

VB
<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:
JavaScript
$.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.

VB
<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:

JavaScript
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)


Written By
Architect App Dev Consultant
Jordan Jordan
Working for Microsoft Consultation Services as a Lead App Dev Consultant.

I have more than 15 years of experience in developing and managing different software solutions for the finance, transportation, logistics, and e-commerce sectors. I’ve been deeply involved in .NET development since early framework versions and currently, I work on different technologies on the ASP.NET stack with a deep passion for Web API, Distributed systems, Microservices, and Microsoft Azure.

Prior to joining Microsoft, I have been awarded the Microsoft Most Valuable Professional (MVP) Award for the years 2015 and 2016 in Visual Studio and Development Technologies, also I’m a regular speaker in local events and Dev user groups.

Comments and Discussions

 
-- There are no messages in this forum --