【问题标题】:Circular reference while serializing EF model to Json将 EF 模型序列化为 Json 时的循环引用
【发布时间】:2016-09-13 20:14:00
【问题描述】:

我知道有很多与这个主题相关的问题,但没有一个能解决我的问题。

我将 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...”异常。

我在这里找到的所有答案都说很难解决,我应该添加

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());

但是,这是一个非常糟糕的解决方案,特别是当我在视图中动态地从视图模型中序列化属性时。它还违背了“全局配置”的全部目的。

有人遇到过这个问题吗?

【问题讨论】:

  • 你能展示你的 JSON 吗?

标签: c# asp.net-mvc entity-framework serialization json.net


【解决方案1】:

您需要将 DefaultSettings 更改为新的。

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.All,
    ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};

来源

【讨论】:

  • 嗨亲爱的@vendettamit 我应该在哪里使用这个代码?
  • 在 global.asax 的 Application_Start() 中使用此代码
【解决方案2】:

默认序列化程序设置需要更改如下。 在 Global.aspx 中,

protected void Application_Start()
{
    var jsonMediaTypeFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
    jsonMediaTypeFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
    jsonMediaTypeFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
}

【讨论】:

  • 请解释为什么需要更改设置
  • 谢谢。这对我有用。但是我不得不删除您设置 PreserveReferencesHandling 的行,因为它使序列化的 JSON 被引用处理对象包装。
【解决方案3】:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings 仅影响 Web API 调用。由于您直接调用JsonConvert.SerializeObject,因此您需要直接将设置传递给它,如下所示,或者设置全局默认设置,如@vendettamit 的答案所示。

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

【讨论】:

  • 感谢您的信息。他们应该在文档中非常清楚地说明这一点,但他们只说“哦,只需添加这个和那个,它就会起作用”。我接受了 vendettami 的回答,因为它更好地保留了我需要的全局配置理念。
  • 好吧,他们可能假设如果您使用 Web API,您将创建一个返回 JSON 的控制器方法,然后从您的视图中通过 AJAX 调用它。在视图本身中手动序列化模型是不常见的。
  • 我正在使用带有 web api 的 mvc 5,但我还没有开始使用 api。我有一个使用 razor 的强类型视图,但根据用户操作,我可能需要序列化模型的某些部分。真的很不寻常
猜你喜欢
  • 1970-01-01
  • 2012-04-30
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多