我知道SO有很多与这个主题相关的问题,但没有一个能解决我的问题。
我使用MVC 5与实体框架6和Newtonsoft.Json.
我有这个例外的常见场景:
Service => Staff => Service
当我尝试在视图中序列化service
对象时,如下所示:
var arr = @Html.Raw(@JsonConvert.SerializeObject(Model.Services));
我得到了"circular reference was detected while serializing an object of type...
"异常。
我在这里找到的所有答案都说它很难解决,我应该添加
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
.PreserveReferencesHandling = PreserveReferencesHandling.All;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
在我的Global.asax
文件中。
嗯,我做了,但就是不起作用。我在MSDN上读了很多文章,他们都说同样的话。我不知道为什么,但这对我来说不起作用。
我能让它工作的唯一方法是在我的控制器中创建整个序列化上下文:
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());
然而,这是一个非常糟糕的解决方案,特别是如果我正在视图中动态地序列化视图模型中的属性。它也违背了"全球配置"的全部目的。
有人面临过这个问题吗?
您需要将DefaultSettings更改为新设置。
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.All,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};
源
默认的序列化程序设置需要更改如下。在Global.aspx中,
protected void Application_Start()
{
var jsonMediaTypeFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
jsonMediaTypeFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
jsonMediaTypeFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
}
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
仅影响Web API调用。由于您直接调用JsonConvert.SerializeObject
,您需要将设置直接传递给它,如下所示,或者设置全局默认设置,如@venattamit的回答所示。
var arr = @Html.Raw(@JsonConvert.SerializeObject(Model.Services, new JsonSerializerSettings
{ PreserveReferencesHandling = PreserveReferencesHandling.All }));