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