1

I have a JQGrid treegrid that I need to move from a ASP.NET MVC project to a WebForms project.

I've decided to use a webservice in the project to return the data for the grid as I don't have much experience writing custom handlers.

Here is my existing grid:

$("#TreeGrid").jqGrid({
                 url: '@Url.Action("GetSPTreeJSON", "Index")',
                 treeGrid: true,
                 datatype: "json",
                 mtype: "POST",
                 treeGridModel: 'adjacency',
                 postData: { currentUserGroup: currentUserGroup },
                 colNames: ["id", "partners"],
                 colModel: [
                        { name: 'id', index: 'id', hidden: true, key: true },
                        { name: 'partners', index: 'name', width: 500, sortable: false, classes: 'pointer' }
                ],                   
                 ExpandColumn: 'partners',                  
                 gridview: true
             });

And existing controller action:

    public JsonResult GetSPTreeJSON(string nodeid, string n_level, Guid currentUserGroup)
    {
        List<TreeNode> list = clientService.GetTreeNodeList(nodeid, n_level, currentUserGroup);

        var jsonData = new
        {
            page = 1,
            total = 1,
            records = 1,
            rows = (
                from TreeNode u in list
                select new
                {
                    cell = new object[] { u.Id.ToString(), u.name, u.level, u.ParentId, u.isLeaf, false }
                }).ToList()
        };

        return Json(jsonData, JsonRequestBehavior.AllowGet);
    }

Sample Json (for root node):

{
   "page":1,
   "total":1,
   "records":1,
   "rows":[
      {
         "cell":[
            "5a1a9742-300f-11d3-941f-036008032006",
            "root node",
            0,
            null,
            false,
            false
         ]
      }
   ]
}

My question is: What exactly is required to get this to work in an asp.net webforms project using json data and webservices?

What I have semi working so far:

Added or changed the following jqGrid options:

url: 'JQGridData.asmx/GetSPTreeJSON', //now points to the webservice
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' }, //looks like it wont hit the webservice if this isn't included
serializeGridData: function (postData) { //looks like this is required because the webservice call will fail if not passed the correct parameters
                    if (postData.nodeid === undefined) postData.nodeid = null;
                    if (postData.n_level === undefined) postData.n_level = null;                 
                    return JSON.stringify(postData);
                },

WebService skeleton that needs to return the JSON:

 [WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string GetSPTreeJSON(string nodeid, string n_level, Guid currentUser)
        {

              List<TreeNode> list = clientService.GetTreeNodeList(nodeid, n_level, currentUserGroup);

            var jsonData = new
            {
                page = 1,
                total = 1,
                records = 1,
                rows = (
                    from TreeNode u in list
                    select new
                    {
                        cell = new object[] { u.Id.ToString(), u.name, u.level, u.ParentId, u.isLeaf, false }
                    }).ToList()
            };

JObject json = JObject.Parse(jsonData);
return = json.ToString();           
        }

EDIT:

Following Olegs advice, I have edited my webservice method as follows:

 public class jqGridRecord
    {
        public Guid Id { get; set; }           
        public string Name { get; set; }
        public int level { get; set; }
        public Guid? parent { get; set; }
        public bool isLeaf { get; set; }
        public bool expanded { get; set; }
    }

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class JQGridData : System.Web.Services.WebService
{
    private readonly ClientService clientService = new ClientService();      


    [WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public JqGridData GetSPTreeJSON(string nodeid, string n_level, Guid currentUser)
    {
        List<TreeNode> list = clientService.GetTreeNodeList(nodeid, n_level, currentUser);

        List<jqGridRecord> data = new List<jqGridRecord>();

        foreach (var i in list)
        {
            jqGridRecord r = new jqGridRecord
            {
                Id = i.Id,
                Name = i.name, 
                level = i.level,
                parent = i.ParentId,
                isLeaf = i.isLeaf,                   
                expanded = false
            };

            data.Add(r);
        }

        int recordsCount = data.Count;                      

        return new JqGridData()
        {
            total = 1,
            page = 1,
            records = recordsCount,
            rows = data
        };
    }
}

public class JqGridData
{
    public int total { get; set; }
    public int page { get; set; }
    public int records { get; set; }
    public List<jqGridRecord> rows { get; set; }
}

and added the following to the jqGrid options:

 colModel: [
                        { name: 'Id', hidden: true, key: true },
                        { name: 'Name', width: 500, sortable: false, classes: 'pointer' }
                ],
jsonReader: { repeatitems: false, root: "d.rows", page: "d.page", total: "d.total", records: "d.records" },

The following JSON is now returned for the root, and I can see the root node in the tree but cant click the + icon to expand it...it seems there is still some kind of problem with the jsonReader?

{
   "d":{
      "__type":"SSDS.iValue.JqGridData",
      "total":1,
      "page":1,
      "records":1,
      "rows":[
         {
            "Id":"5a1a9742-3e0f-11d3-941f-006008032006",
            "Name":"acsis Limited",
            "level":0,
            "parent":null,
            "isLeaf":false,
            "expanded":false
         }
      ]
   }
}
woggles
  • 7,444
  • 12
  • 70
  • 130

1 Answers1

2

I see two clear errors:

  • you should define some class for example TreeGrid which describes var jsonData object which you use in WebMethod. You should remove manual conversion of the object to string. Instead of that web method have to return object TreeGrid instead of string. You can't return raw data from ASMX web service and .NET framework convert always the object to the string.
  • .NET framework place the full response of the web method inside of d prpterty. So the response will be
{
    "d": {
       "page":1,
       "total":1,
       "records":1,
       "rows":[ ...]
}

So you should add the option jsonReader to jqGrid:

jsonReader: {
    root: "d.rows",
    page: "d.page",
    total: "d.total",
    records: "d.records"
}

By the way if you do decide to use ASHX handle instead of ASMX web service you can improve a little performance of your application. The example of the corresponding C# code you can find and download in the answer. }

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks Oleg, I've applied and understand the changes you've suggested...but still have an issue where I cant expand the root node. Please see my edit! – woggles Apr 30 '13 at 07:32
  • Ah figured it out..the sting for ExpandColumn wan't correct! Thanks for the help :) – woggles Apr 30 '13 at 08:07
  • @woggles: The code which you use now in web service should do the same what your ASP.NET application did. TreeGrid send tree parameters to the server `nodeid`, `parentid` `n_level` (see [the documentation](http://www.trirand.com/jqgridwiki/doku.php?id=wiki:adjacency_model#what_we_post)). The server should returns the children of the node with `parentid` which be expended. You should change you server code – Oleg Apr 30 '13 at 08:07
  • @woggles: You are welcome! I'm glad that the problem is solved now. – Oleg Apr 30 '13 at 08:09