Sean Thoman
Sean Thoman

Reputation: 7489

Populating jqGrid with JSON -- Performance using WCF vs ASMX for the backend

I am using an ASMX back-end to populate a jqGrid client-side, including client-side paging of the grid so all rows of data are loaded at once. My question is whether this is the best approach performance and reliability wise? Also, if WCF would be better than ASMX is it fairly easy to convert this existing set up to WCF (I'm guessing I should use REST-style WebGet methods, but I'm not positive). Just want everything to be as fast and responsive as possible, little to no postbacks ideally.

Here is the ASMX code:

public class JQGrid
{
    public class Row
    {
        public int id { get; set; }
        public List<string> cell { get; set; }
        public Row()
        {
            cell = new List<string>();
        }
    }

    public int page { get; set; }
    public int total { get; set; }
    public int records { get; set; }
    public List<Row> rows { get; set; }
    public JQGrid()
    {
        rows = new List<Row>();
    }
}  

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.None)]
[ScriptService]
public class JQGridService : System.Web.Services.WebService
{
    [WebMethod(EnableSession = true)]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public JQGrid GetJQGrid(int pageIndex, int pageSize, string sortIndex, string sortDirection)
    {
        DataTable dt = GetDataTable( // command string ); 

        if (dt == null)
            throw new Exception("Unable to retrieve data.");

        JQGrid jqGrid = new JQGrid();

        foreach (DataRow sourceRow in dt.Rows)
        {
            JQGrid.Row targetRow = new JQGrid.Row();
            targetRow.id = Convert.ToInt32(sourceRow["ID"]);
            targetRow.cell.Add(sourceRow["ID"].ToString());
            targetRow.cell.Add(sourceRow["SomeColumn"].ToString());
            jqGrid.rows.Add(targetRow);
        }

        jqGrid.page = pageIndex; 
        jqGrid.records = jqGrid.rows.Count;
        jqGrid.total = jqGrid.rows.Count;  // Set this to total pages in your result...          

        return jqGrid;
    }
}

Client-side JS:

function getData(pdata)
     {
         var params = new Object();

        params.pageIndex = pdata.page; 
        params.pageSize = pdata.rows;
        params.sortIndex = pdata.sidx;
        params.sortDirection = pdata.sord;

        $.ajax(
            {
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "JQGridService.asmx/GetJQGrid",
                data: JSON.stringify(params),
                dataType: "json",
                success: function (data, textStatus) 
                {
                    if (textStatus == "success") {
                        var thegrid = $("#jqGrid")[0];

                        thegrid.addJSONData(data.d);
                    }
                },
                error: function (data, textStatus) {
                    alert('An error has occured retrieving data!');
                }
            });
        }

        function pageLoad() { loadGrid() }; 

        function loadGrid() {

            $("#jqGrid").jqGrid({

                gridComplete: function() {
                    $("#jqGrid").setGridParam({ datatype: 'local' });  
                },
                datatype: function (pdata) {
                    getData(pdata);
                },
                colNames: ['ID', SomeColumn],
                colModel: [
                    { name: 'ID', index: 'ID', width: 150 },
                    { name: SomeColumn, index: SomeColumn, width: 250}],
                rowNum: 10,
                rowList: [10, 20, 30],
                viewrecords: false,
                pagination: true,
                pager: "#jqPager",
                loadonce: true,
                sortorder: "desc",
                sortname: 'id',
                cellEdit: false
            });
        }

Upvotes: 1

Views: 2699

Answers (1)

David Hoerster
David Hoerster

Reputation: 28701

I found this response from a Microsoft moderator (Gregory Leake) on their forums about whether to go with ASMX or WCF web services. The key quote (for me):

WCF is Microsoft's strategic communication technology for .NET. ASMX is supported; but is not the future

Since the 3.5 SP1 release of the framework, I personally haven't used ASMX services and with the WCF WebHttp Services functionality released in the .NET 4 framework, I haven't looked back.

Changing over to use WCF REST services from ASMX would probably just involve:

  1. Decorating your JQGrid class with DataContract and DataMember attributes;
  2. Obviously, creating the WCF service interface (IJQGridService) and implemented class (JQGridService). Your JQGridService's implementation probably would change much at all except for the attributes on the class by replacing the current ones with a WebGetAttribute (on the interface) and a AspNetCompatibilityRequirementsModeAttribute (on the implementation class).
  3. Some web.config changes since you'll have a <system.serviceModel> section now; but if you add a AJAX-enabled WCF service to your project, most of those settings will already be in place for you. The only thing you'd probably want to change is the endpointBehavior to use <webHttp/> instead of <enableWebScript>.
  4. You shouldn't have to make any changes to your client-side JS, except changing the URL if your service name changes (which it probably will) and you should also change to using a GET verb from a POST since you're just retrieving data. jqGrid does a great job of handling the required parameters for paging on the query string.

Other than that, you're probably good to go.

I hope this helps. If there are other questions, let me know and I'll update this answer.

Good luck!

Upvotes: 1

Related Questions