Bit of Technology

  • Archive
  • About Me
    • Advertise
    • Disclaimer
  • Speaking
  • Contact

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

April 6, 2013 By Taiseer Joudeh Leave a Comment

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 response then 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 which they are Courses, and Attendees.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<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.

1
{"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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$.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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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.

Related Posts

  • Boost UI Rendering with Client Side Templating

Filed Under: AJAX, ASP.NET, CodeProject, Javascript, jQuery Tagged With: AJAX, Javascript, jQuery, JSON

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About Taiseer

Husband, Father, Consultant @ MSFT, Life Time Learner... Read More…

Buy me a coffeeBuy me a coffee

Recent Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4

Blog Archives

Recent Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4

Tags

AJAX AngularJS API API Versioning ASP.NET ASP.Net 5 Authentication Autherization Server Azure Active Directory Azure Active Directory B2C Azure AD B2C basic authentication Code First Dependency Injection Documentation Entity Framework Entity Framework 7 Facebook Foursquare API Google Authenticator Identity jQuery JSON JSON Web Tokens JWT MVC 6 Ninject OAuth OData Resource Server REST RESTful RESTful. Web API Single Page Applications SPA Swagger-ui Swashbuckle TFA Token Authentication Tutorial Two Factor Authentication Web API Web API 2 Web API Security Web Service

Search

Copyright © 2022 · eleven40 Pro Theme on Genesis Framework · WordPress · Log in