Reputation: 1552
I know that are tons of questions related to this topic all over SO but none of them solved my problem.
I'm using MVC 5 with Entity Framework 6 and Newtonsoft.Json.
I have the usual scenario for this exception:
Service => Staff => Service
When I try to serialize a service
object in my view, like this:
var arr = @Html.Raw(@JsonConvert.SerializeObject(Model.Services));
I get the "circular reference was detected while serializing an object of type...
" exception.
All the answers I found here say it is wasy to solve, I should just add
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
.PreserveReferencesHandling = PreserveReferencesHandling.All;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
in my Global.asax
file.
Well, I did, and it just doesn't work. I read a bunch of articles on MSDN an they all say the same thing. I don't know why, but it just doesn't work for me.
The only way I could make it work, was to create the whole serialization context in my controller:
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.All,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};
var serializer = JsonSerializer.Create(settings);
var msmStream = new MemoryStream();
var txtWriter = new StreamWriter(msmStream);
var writer = new JsonTextWriter(txtWriter) { Formatting = Formatting.Indented };
serializer.Serialize(writer, services);
var json = Encoding.ASCII.GetString(msmStream.GetBuffer());
However, this is a terrible terrible solution, specially if I'm serializing a property from my view model on the fly in the view. It also defeats the whole purpose of a "global configuration".
Has anybody faced this problem?
Upvotes: 2
Views: 6466
Reputation: 11
The default serializer settings needs to be changed as follows. In Global.aspx,
protected void Application_Start()
{
var jsonMediaTypeFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
jsonMediaTypeFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
jsonMediaTypeFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
}
Upvotes: 1
Reputation: 129667
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
only affects Web API calls. Since you are calling JsonConvert.SerializeObject
directly, you either need to pass the settings directly to it as shown below or else set up the global default settings as shown in @vendettamit's answer.
var arr = @Html.Raw(@JsonConvert.SerializeObject(Model.Services, new JsonSerializerSettings
{ PreserveReferencesHandling = PreserveReferencesHandling.All }));
Upvotes: 0
Reputation: 14677
You need to change the DefaultSettings to new ones.
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.All,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};
Source
Upvotes: 2