将EF模型序列化为Json时的循环引用

我知道有很多关于这个主题的问题,但是没有一个问题解决了我的问题。

我正在使用MVC 5和Entity Framework 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... ”exception。

我在这里找到的所有答案都说它很难解决,我应该补充一下

 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 ,您需要将设置直接传递给它,如下所示,或者设置全局默认设置,如@ vendettamit的答案所示。

 var arr = @Html.Raw(@JsonConvert.SerializeObject(Model.Services, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }));