Ext JS JsonStore and Linq to JSON Gotcha

Here's a little gotcha that had be scratching my head for a moment. I was testing the Grid component of the excellent Ext JS framework when I ran into a problem loading the JSON result into the grid.

It seemed simple enough - populate the grid from JSON data returned by a controller action method. When I ran the code the grid wasn't populated: the Ext JSONReader was throwing an error "root is undefined". I checked and double checked everything but could not see what the problem was.

Here's the JavaScript to create the JsonStore for the grid:

var ds = new Ext.data.JsonStore({
    url: '/Home/GetData',
    totalProperty: 'totalRecords',
    root: 'requests',
    id: "ReqNo",
    fields: ['Division', 'Department'],
    listeners: {
        loadexception: function(proxy, store, response, e) {
            alert(e.message);
        }
    }        
}); 

Here's the controller method that returns the JSON:

public JsonResult GetData(int? start, int? limit)
{
    limit = limit ?? 25;
    start = start ?? 0;
   

    string dataPath = HttpContext.Server.MapPath("~/Data/TestData.xml");
    XDocument xDoc = XDocument.Load(dataPath);
    var results = from requests in xDoc.Descendants("requests")
                  select new
                  {
                      totalRecords = requests.Elements("request").Count(),
                      requests = (from request in requests.Elements("request")
                                  select new NBWeb.Models.Request
                                  {
                                      Division = request.Element("Division").Value,
                                      Department = request.Element("Department").Value
                                  }).Skip((int)start).Take((int)limit)
                  };
    return this.Json(results);
}

And here's an example of the JSON it emits:

[{
    "totalRecords":200,
    "requests":[
        {"Division":"Division 1","Department":"Department 5",},
        {"Division":"Division 2","Department":"Department 4",},
        {"Division":"Division 3","Department":"Department 5",},
        {"Division":"Division 4","Department":"Department 6",},
    ]
}]

Eventually, upon examining the JSON for the tenth time, it dawned on me - the entire JSON data was nested in a redundant outer array. So the JsonStore root property was not being found - it was looking for:

obj["requests"]

but would need to look for:

obj[0]["requests"]

So it was the controller returning slightly malformed JSON. It's a bug in my code - I need to return the inner result of the Linq select rather than the entire result. So I need to take the FirstOrDefault record from the results, like so:

public JsonResult GetData(int? start, int? limit)
{
    limit = limit ?? 25;
    start = start ?? 0;

    string dataPath = HttpContext.Server.MapPath("~/Data/TestRequests2500.xml");
    XDocument xDoc = XDocument.Load(dataPath);
    var results = (from requests in xDoc.Descendants("requests")
                  select new
                  {
                      totalRecords = requests.Elements("request").Count(),
                      requests = (from request in requests.Elements("request")
                                  select new NBWeb.Models.Request
                                  {
                                      Division = request.Element("Division").Value,
                                      Department = request.Element("Department").Value,
                                  }).Skip((int)start).Take((int)limit)
                  }).FirstOrDefault();

    return this.Json(results);
}

And here's the corrected JSON it emits (note the absence of the outer square brackets):

{
    "totalRecords":200,
    "requests":[
        {"Division":"Division 1","Department":"Department 5",},
        {"Division":"Division 2","Department":"Department 4",},
        {"Division":"Division 3","Department":"Department 5",},
        {"Division":"Division 4","Department":"Department 6",},
    ]
}

Seems like a dumb mistake to make but it took a bit of debugging to find it - hopefully this post will save someone out there some time.

Published: Friday, 24 October 2008 05:22 PM by Steve

Tags: MVC Ext JS ASP.Net

Comments: 0 Comments