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 Gotcha ASP.Net

Comments: 5 Comments