2

Recently, I searched for a good engine to generate charts with Asp.Net Mvc 3. I finally found FusionChart which have a very nice varieties of chart types.

For helping me creating the xml required to display the chart, I found the project Libero. This project create a level of abstraction between the xml and the object model to define the properties of the graphic.

The project use Mvc2 and I tried to convert it to Mvc3. All the samples works perfectly except one; a sample with ajax call.

In the sample, the controller returns a ContentResult that returns a xml to update the graphic dynamically. The project works perfectly in Mvc2 but not in Mvc3.

Here is the code in the controller:

  public ActionResult GetSalesXmlData(string period, string chartType, string chartTemplate)
  {
     var salesXmlData = this.Content(GetSalesChart(period, chartType, chartTemplate).ToXML(), "text/xml");

     return salesXmlData;
  }

And here is the code in the view:

$.ajax({
    url: "/Home/GetSalesXmlData",
    type: "POST",
    data: { chartType: chartType, chartTemplate: chartTemplate, period: period },
    dataType: "application/JSON",
    success: function (data) {
        Chart01.xmlData   = data;
        Chart01.chartType = chartType;
        Chart01.showChart();
    },
    error: function () {
      alert("XMLHttpRequest=" + XMLHttpRequest.responseText + "\ntextStatus=" + textStatus + "\nerrorThrown=" + errorThrown);
    }
});

When I try to execute this code in Mvc3, I receive this error:

textStatus=parsererror errorThrown=No conversion from xml to application/json

After searching for a while, I found how to correct my problem in this stackoverflow question.

After reading this post, I changed my controller code to this:

  public JsonResult GetSalesXmlData(string period, string chartType, string chartTemplate)
  {
     var salesXmlData = this.Json(GetSalesChart(period, chartType, chartTemplate).ToXML(), "text/xml");

     return salesXmlData;
  }

And my ajax call to this:

$.ajax({
    url: "/Home/GetSalesXmlData",
    type: "POST",
    data: { chartType: chartType, chartTemplate: chartTemplate, period: period },
    dataType: "text json",
    success: function (result) {
        Chart01.xmlData   = result;
        Chart01.chartType = chartType;
        Chart01.showChart();
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
      alert("XMLHttpRequest=" + XMLHttpRequest.responseText + "\ntextStatus=" + textStatus + "\nerrorThrown=" + errorThrown);
    }
});

My question is: Why after converting my project from Mvc2 to Mvc3, I must change the result returns by the controller from ContentResult to JsonResult and in my view, the dataType value from application/JSON to text json?

Thank you for your time.

Community
  • 1
  • 1
Samuel
  • 12,073
  • 5
  • 49
  • 71

1 Answers1

3

In your original example, you were instructing jQuery to parse the response as JSON even though it was XML. If you upgraded from an older version of jQuery to a newer one as part of the MVC upgrade process, that would explain the parser error. Older versions of jQuery were fairly fast and loose about parsing AJAX responses, but later versions have begun using JSON.parse when jQuery believes the response to be JSON or you explicitly tell it to treat them as such.

Your newer version works around this by taking the XML and JSON-serializing that XML. While that technically does work, it has added an inefficient layer of redundant serialization.

Does your original approach work if you change the dataType to text/xml?

Speaking of efficiency, have you considered using JSON instead of XML? FusionCharts appears to support that. Then, you could avoid the XML altogether, use a more compact serialization over the wire, and take advantage of the browser's native JSON.parse method to more efficiently unpack the response too.

Dave Ward
  • 59,815
  • 13
  • 117
  • 134
  • I would like to have the deep knowledge that you have. I will surely read and read again your recommendations and search more about the version of jQuery that I use, the different dataType that I can use with ContentResult. Thank you again. I will give you back about my results. – Samuel Apr 03 '12 at 01:14