Json and Entity Frameworks
May 4, 2010 Leave a comment
I started digging deeper into Ajax and Json in a MVC solution when I came across an interesting gotcha. I wanted to have a table with some data be assocaited with a drop down – a very common pattern. I started using Entity Frameworks and I created a couple of Json methods to expose some of the classes from the EF Data Context.
The most import thing to recognize is on line 23 and 34. If you do that I have on line 41, you get an error. Gotcha #1 is that there is no way to detect the error using this code:
$.ajax({
type: "POST",
traditional: true,
url: "/Territory/GetRegions",
dataType: "json",
success: function (data) {
$.each(data, function () {
//Stuff
}
});
Because there is no error handler implemented. Fortunately, Fiddler came and saved the day:
In addition, you can add an error handler with the Error property:
error: function(XMLHttpRequest) {
alert(XMLHttpRequest.responseText);
}
And now that I think about it, the gotcha makes sense. The return from entity framework has all of these relation properities, etc… that json simply does not care about. My lesson learned is to use DTOs where communicating with Json, don’t use the classes created by EF
In any event, once the Json methods got working, I needed to hook them up to the controls on hte form. I started 1st with ASP.NET controls (drop down list and grid view) but the client side ID was getting screwed up (I think there is a fix in 4.0, need to investigate) so I used plain old HTML controls and implemented the following 2 loads. The 1st goes on the page load for the select list:
function LoadRegionList() {
$.ajax({
type: "POST",
traditional: true,
url: "/Territory/GetRegions",
dataType: "json",
success: function (data) {
$.each(data, function () {
$("#SelectRegion").append($("<option />").val(this.regionId).text(this.regionDescription));
});
}
});
}
And the other goes on the select list changed event – updating the table
function LoadTerritoryList() {
$("#TerritoryTable tr:gt(0)").html("");
var regionId = $("#SelectRegion").val();
var postData = { RegionID: regionId };
$.ajax({
type: "POST",
traditional: true,
url: "/Territory/GetTerritories",
data: postData,
dataType: "json",
success: function (data) {
$.each(data, function () {
$("#TerritoryTable").append("<tr><td>" + this.territoryID + "</td><td>" + this.territoryDescription + "</td></tr>");
});
}
});
I don’t like stringing together HTML (the <option>,<td>,<tr> tages) but I can’t find a simpler way. It seems that there is no separation of concerns I am placing data into markup.
Once those methods were implemented – volia! I had a table that changed with every change of the select list. Very cool.
I am still wondering if the developer experience taking a step-backwards might be worth the trade off – the user experience is much much better than ASP.NET post-back and even ASP AJAX update panels…