10

I have an asp.net MVC 3 controller action method like this:

public JsonResult GetRecordingRates(int Id)
{            
    List<DefaultRateChart> defaultRateCharts = new List<DefaultRateChart>();
    using (IDefaultRateChartManager defaultRateChartManager = new ManagerFactory().GetDefaultRateChartManager()) {
       defaultRateCharts = defaultRateChartManager.GetAll().Where(rc => rc.Currency.Id == Id && (!rc.NumberPrefix.StartsWith("#") || rc.NumberPrefix.StartsWith("Default")) && rc.AccountCredit == "Credit").ToList();
    }
    return Json(defaultRateCharts);
}

I want to send this list to jquery ajax success method but I am getting 500 Internal Server Error

my ajax call is like this:

$.ajax({
type: "POST",
dataType: "json",
url: "/Home/GetRecordingRates",
data: {
    Id: $("#hdCurrencyId").val()                 
},
success: function (data) {
        alert(data);
   }
}); 

In firebug XHR under response tab, it says:

A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'.

[EDIT]

I changed the action method to this:

public JsonResult GetRecordingRates(int Id)
{
    List<DefaultRateChart> defaultRateCharts = new List<DefaultRateChart>();
    using (IDefaultRateChartManager defaultRateChartManager = new ManagerFactory().GetDefaultRateChartManager())
    {
        defaultRateCharts = defaultRateChartManager.GetAll().Where(rc => rc.Currency.Id == Id && (!rc.NumberPrefix.StartsWith("#") || rc.NumberPrefix.StartsWith("Default")) && rc.AccountCredit == "Credit").ToList();
    }

    return this.Json(
        new
        {
            Result = (from obj in defaultRateCharts select new { Id = obj.Id, DialPrefix = obj.NumberPrefix, Rate = obj.PurchaseRates })
        }
        , JsonRequestBehavior.AllowGet
     );
}

and I dont get that error now but how can I parse the collection in ajax success. I changed success to following but it is not adding rows in table.

success: function (data) {
            var row = $('<tr>');
            for(var i = 0; i < data.length; i++) {
                row.append($('<td>').html(data[i]));
            }   

            $('#results').append(row);                                      
            jQuery('#RecordingRates').dialog({ closeOnEscape: false });
            $(".ui-dialog-titlebar").hide();
            $("#RecordingRates").dialog({ dialogClass: 'transparent' });
            $('#RecordingRates').dialog('open');
           }
    }); 

In Firebug Net => XHR=> Json, It shows following JSON:

[Object { Id=

1

,  DialPrefix=

"1"

,  Rate=

2.6

}, Object { Id=

3

,  DialPrefix=

"2"

,  Rate=

2.6

}, Object { Id=

5

,  DialPrefix=

"7"

,  Rate=

3.5

}, 3 more...]


0
    Object { Id=

1

, DialPrefix=

"1"

, Rate=

2.6

}

1
    Object { Id=

3

, DialPrefix=

"2"

, Rate=

2.6

}

2
    Object { Id=

5

, DialPrefix=

"7"

, Rate=

3.5

}

3
    Object { Id=

7

, DialPrefix=

"8"

, Rate=

6

}

4
    Object { Id=

9

, DialPrefix=

"Default"

, Rate=

5

}

5
    Object { Id=

15

, DialPrefix=

"Subscription"

, Rate=

15

}
Dan Homola
  • 3,819
  • 1
  • 28
  • 43
DotnetSparrow
  • 27,428
  • 62
  • 183
  • 316

2 Answers2

4

This happens when two or more objects in your JSON points to each other, the serializer cannot reflect those into JSON. You should use the Newtonsoft serializer (It is explained here how to do it: Using JSON.NET as the default JSON serializer in ASP.NET MVC 3 - is it possible?)

There are several things you can do. The first was one is let the configuration manager know to ignore or preserve those references like this:

        config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;

or

you could annotate the properties you don't want to be serialized in the objects (So a circular reference won't exist). With the annotation [JsonIgnore] like this:

public class Order
{
    [JsonIgnore]
    public virtual ICollection<OrderLines> OrderLines{ get; set; } 
}
Community
  • 1
  • 1
Nick N.
  • 12,902
  • 7
  • 57
  • 75
0

how can I parse the collection in ajax success. I changed success to following but it is not adding rows in table.

You are returning a collection with the following fields: Id, DialPrefix, Rate, and you are not using them.

var row = $('<tr>');
for(var i = 0; i < data.length; i++) {
    row.append($('<td>').html(data[i]));
}   

$('#results').append(row);  

You need to add them to your loop:

row.append($('<td>').html(data[i].DialPrefix));
row.append($('<td>').html(data[i].Rate));
von v.
  • 16,868
  • 4
  • 60
  • 84
  • Have you checked that you actually have data? Try printing in the console (`console.log(data)`). – von v. Apr 29 '13 at 13:55
  • alert won't help you, do a `console.log` and in FF or Chrome, go to the console tab and you should see your collection (array) printed out, if you have some data received. On the server side, have you checked that `from obj in defaultRateCharts select` produces result? Put that in a variable first and see if it indeed have a value. – von v. Apr 29 '13 at 14:07
  • I updated question again. sorry I understand it is new question. – DotnetSparrow Apr 29 '13 at 14:08
  • Are you sure that `results` is your `table`? and that it is not hidden or overwritten (z-index) by some element? Do an `alert($('#results').html())` after the loop and see if the rows are added - but they should be based on your code that I updated (answered to). – von v. Apr 29 '13 at 14:10