【问题标题】:"Self Referencing Loop Detected" exception with JSON.NetJSON.Net 的“检测到自引用循环”异常
【发布时间】:2017-03-21 05:22:25
【问题描述】:

我有这段代码可以将Route 对象列表发送到我的视图(ASP.Net MVC):

public ActionResult getRouteFromPart(int partId)
{
    List<Route> routes = _routeService.GetRouteByPartType(partId);

    if (routes == null)
    {
        return this.AdvancedJsonResult(null, JsonRequestBehavior.AllowGet);
    }

    return this.AdvancedJsonResult(new
    {
        Routes = routes
    }, JsonRequestBehavior.AllowGet);
}

但我在 AdvancedJsonResult 类中遇到了一个异常:

if (Data != null)
{
    var settings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    };

    string result = JsonConvert.SerializeObject(this.Data, this.Formatting, settings);
    response.Write(result);
}

我已经尝试过“ReferenceLoopHanding.Ignore”技巧来使异常静音,但列表仍然没有传递给视图。

当我将routes 更改为单个对象而不是列表时,该代码有效,因此我认为该代码不喜欢使用列表。

我是这个项目的新手,所以我不知道如何解决这个问题并让它对使用 List 感到满意...

编辑:这是完整的异常消息,发生在string result = JsonConvert... 行。

检测到类型为“System.Data.Entity.DynamicProxies.PartNumber_B135A5D16403B760C3591872ED4C98A25643FD10B51246A690C2F2D977973452”的自引用循环。路径'routes[0].incomingLots[0].partNumber.partType.partNumbers'。

【问题讨论】:

标签: c# asp.net json serialization json.net


【解决方案1】:

错误信息的意思是存在一个自引用循环。当您请求某些实体时,您必须设置不想获取所有链接实体的数据库上下文。可以通过在 DbContext 类构造函数中添加两行来禁用自引用循环来完成,如下所示:

public YourDbContext() : base("name = YourDbContext")
{       
    //add these lines in order to avoid from "Self referencing loop detected for ..." error
    this.Configuration.LazyLoadingEnabled = false;
    this.Configuration.ProxyCreationEnabled = false;
}

希望这会有所帮助...

【讨论】:

  • 我不喜欢这种答案,因为您正在关闭默认启用的 EF6 功能,并且这段代码可能会破坏程序的其他部分。你应该解释它的作用以及它有什么样的影响。
【解决方案2】:

基于 Json.net 的默认 Json 格式化程序的正确答案是将 ReferenceLoopHandling 设置为 Ignore。

只需将其添加到 Global.asax 中的Application_Start

HttpConfiguration config = GlobalConfiguration.Configuration;

config.Formatters.JsonFormatter
            .SerializerSettings
            .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

这是正确的方法。它将忽略指向对象的引用。

其他响应侧重于通过排除数据或制作外观对象来更改返回的列表,有时这不是一种选择。

使用 JsonIgnore 属性来限制引用可能很耗时,如果您想从另一个点开始序列化树,这将是一个问题。

复制this answer

【讨论】:

    猜你喜欢
    • 2012-11-10
    • 1970-01-01
    • 2017-02-13
    • 2016-09-15
    • 2016-02-15
    • 2014-02-05
    • 1970-01-01
    • 2016-04-26
    相关资源
    最近更新 更多