Configuring jqGrid 3.5 to work with ASP.NET web forms and JSON

If you are an ASP.NET web developer using jQuery for AJAX, you would have probably got used to passing parameters through DTO (Data Transfer Objects) as suggested by Dave in Encosia.com. This is a clean and simple approach for passing parameters from client to server.

Unfortunately, many jQuery plugins are not coded this way and need to be tweaked. Same is the case with jqGrid, which is an excellent jQuery grid plugin. So below are the simple tweaks to be made for jqGrid to support DTO's.

At a basic level, these tweaks should be  done in the "grid.base.js" file. If you are using plugins for inline edit or any other feature which makes AJAX calls, the same changes have to be made there also.

There are things which need to be changed in all AJAX calls made by the plugin:

1. Building a Data Transfer Object(DTO).

2. Setting the content-type to "application/json".

3. Convert the input object into  JSON string.

4. Filtering .NET's "d" parameter in the AJAX success function.

1. Building a DTO: In "grid.base.js", search for the code "populate = function() { ", which is the definition of populate function (This is in line 577). In this function, add the code in bold, above the switch statement (which is in line 588).

var jsObj = { 'obj': ts.p.postData }; //Building a DTO
switch (dt) {
                    case "json":
                    case "xml":
                    case "script":

2. Setting the content-type to "application/json":

  In line 593, add the JSON content type as a parameter to $.ajax function.

3. Convert the input object into  JSON string:

 In the same lin(593), replace the data parameter with JSON stringified DTO.

The code change for (2) and (3) will now be:

  Old Code:  $.ajax({url:ts.p.url,type:ts.p.mtype,dataType: dt ,data: ts.p.postData, 

  Tweaked code: $.ajax({ url: ts.p.url, type: ts.p.mtype, dataType: dt, contentType: 'application/json; charset=utf-8', data: JSON.stringify(jsObj),

 4. Filtering .NET's "d" parameter in the AJAX success function:

Finally, filter .NET's "d" parameter in the line 596 like below:

  Old code:   if(dt === "json" || dt === "script") addJSONData($.jgrid.parse(req.responseText),ts.grid.bDiv,rcnt);

  Tweaked code:  if (dt === "json" || dt === "script") addJSONData($.jgrid.parse(req.responseText).d, ts.grid.bDiv, rcnt);

That's it! The grid should now be able to handle JSON objects as input parameters and should bind JSON data successfully. Note that I have done these tweaks in jqGrid 3.5. The same concept applies to lower versions of jqGrid too. However, the line number and variables used in AJAX calls differ.

Hope this article would save the time of many enthusiasts, who want to use jqGrid in their ASP.NET projects. I shall come up with a detailed post on other common problems shortly.

Filtering .NET 3.5 returned JSON with jQuery

In .NET 3.5, when a Web service class is decorated with “ScriptService” attribute, the web service returns data in JSON format [MSDN]. I have demonstrated this with a simple example in the article, Passing JSON objects in .NET 3.5.

Let us consider that our “person” class has several properties, of which only few are useful on the client side for data binding. We can filter this object in two ways:

1. On the server side:- Create a dictionary object [System.Collections.Generic.Dictionary(Of TKey, TValue)], add the desired properties to dictionary object and return it.

2. On the client side:- In cases where a quick filter has to be done without touching server side code, we can use jQuery’s each function to create a custom JSON object.

Suppose you want to filter only “country” and “code” out of the below JSON data,

var players = 
[{ "country": "India", "code": "Ind", "name": "Sachin" },
{ "country": "Sri Lanka", "code": "SL", "name": "Murali" },
{ "country": "Australia", "code": "Aus", "name": "Shane" },
{ "country": "West Indies", "code": "WI", "name": "Lara"}];

you can simply write the below jQuery code:

var newObject = {}; //Creating a new object
$.each(players, function() { //Looping through our players array using jQuery's each function
    newObject[this.country] = this.code; //Creating our custom "name/value" pair
});

So, our newObject will contain new data(having only “country” and “code”). If you want to access country code, you can simply say “newObject.India”, which gives “Ind”.

This tip is particularly useful in cases like filling dropdown lists with JSON data. By default, the server’s JSON data contains several properties which are not required. In such cases, this client side filter comes as a handy tip :)

Customizing jQuery plugins for "d parameter" in .NET 3.5 JSON response.

I was trying to use jqGrid, an excellent jQuery based grid, for building a zero postback page. It's configuration is very simple, similar to flexigrid, but has many additional features like inline editing, subgrids etc.

What jqGrid expects is a JSON response having few objects and arrays, which are mapped to columns in the grid inside the grid.base.js file, like this.

Though the grid's AJAX call is successful, data is not being bound to thegrid. The reason is, .NET 3.5 returns JSON object which is prefixed with a "d" parameter like this.

So, to map the JSON data to the grid, we have to manually parse the AJAX response and separate the "d" parameter in AJAX success callback. This applies not only to jqGrid, but also to all jQuery plugins which expect JSON response.

I was about to write more on why .Net 3.5 prefixes "d" to JSON response, how it enhances security and how to parse it easily., but incidentally, Dave ward explained the concept excellently in his latest article: http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again

So no more worrying about .Net's "d" again :)

Passing JSON objects in .NET 3.5

In my previous post, I have explained how to pass complex types using jQuery and JayRock in .NET 2.0 framework. I was digging a bit into Dave’s example (using complex types to make calling services less complex) in .NET 3.5 framework, to find how easier JSON serilaization/deserialization can be made.

When a Web service class is decorated with “ScriptService” attribute, which is in the System.Web.Script.Services namespace in .NET 3.5, the web service returns data in JSON format [MSDN]. Whether the returned value is a string or an object, it will be in JSON format. So no need of writing chunks of code for serializing objects explicitly.

Therefore, all that we need to do is to simply decorate our web service class with “ScriptService” attribute and  return an object from the server. So, to create a JSON object like this:

{"d":{"FirstName":"Krishna","LastName":"Chaitanya","City":"Hyd","State"
:"Andhra","Country":"India"}}

We can simply return a person object like this:

<WebMethod()> _
    Public Function fnFetchDetailsClass() As Person
        Dim objPerson As New Person
        Try
            objPerson.FirstName = "Krishna"
            objPerson.LastName = "Chaitanya"
            objPerson.City = "Hyd"
            objPerson.State = "Andhra"
            objPerson.Country = "India"
        Catch ex As Exception
 
        End Try
        Return objPerson
    End Function

In some situations (like in client side templating), we might need to create custom, complex JSON objects on the fly. In such situations, we can make use of .NET’s “ListDictionary” and “ArrayList” classes.

The above example can be re-written using ListDictionary as:

<WebMethod()> _
Public Function fnFetchDetails() As ListDictionary
    Dim jsonObj As New ListDictionary
    Try
        jsonObj.Item("fname") = "Krishna"
        jsonObj.Item("lname") = "Chaitanya"
        jsonObj.Item("city") = "Hyd"
        jsonObj.Item("state") = "Andhra"
        jsonObj.Item("country") = "India"
        Return jsonObj
    Catch ex As Exception
        jsonObj.Item("Error") = "Error at server"
        Return jsonObj
    End Try
End Function

Thus, using JSON is made easier in .NET 3.5.

Here is a simple demo which makes things clear. (I have used jQuery for making AJAX calls.)

(Note: ListDictionary stores values in Name/Value pairs, which is useful in building JSON Object. Similarly, an ArrayList can be used to build JSON Arrays. Therefore, these two can be used instead of JsonObject and JsonArray classes of Jayrock in my post Converting ASP.NET DataTable to JSON using JayRock.)