While developing an ASP.NET MVC app, I'm finding a few places where my JsonResult actions throw an exception "A circular reference was detected while serializing an object".
For now, I'm removing the references in question, but ideally I'd like to simply mark the property such that the JSON serializer ignores it.
Can anyone suggest how I might do this?
I've generally found that for complex objects its best to just serialize by creating a temporary 'inbetween' object :
For instance for testimonials I do the following. I actually do this in the codebehind for my ASPX model page.
This creates a nice JSON object. You'll notice I can even refactor my model and the page will still work. Its just another layer of abstraction between the data model and the page. I dont think my controller should know about JSON as much as possible, but the ASPX 'codebehind' certainly can.
In my ASPX I just do this in a block:
I'm ready for the backlash against this suggestion... bring it on...
I'm not accessing data, merely reformatting a model for the View. This is 'view model' logic, not 'controller model' logic.
The cleanest approach i've found is to use a combination of [DataContract] on the class and [DataMember] on the properties you want to serialize. The DataContract attribute tells the various serializers to ignore any property that doesn't have the DataMember attribute.
There are two major benefits compared to using ScriptIgnoreAttribute. First, it doesn't have a dependency on the System.Web.Extensions assembly. Second, it works with other types of serialization, not just JSON. For example, if you're using the new Web API in MVC 4, the DataContract/DataMember approach will work with the XML serializer as well.
Consider the scenario where your entities are stored in an shared library and reused across various projects - you don't want a dependency on System.Web.Extensions, and you want to loosely describe serialization rules - not hardcode behavior specific to JSON, XML, etc.
I would advise to use JSON.NET. It allows to serialize circular references and provides much more serialization options.
[ScriptIgnore] should work for you.
What Simon said. Add a little AutoMapper action to keep code weight under control.