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



我知道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 }));

相关内容

  • 没有找到相关文章

最新更新