C# 如何停止.Net核心Web API中的自引用循环?

C# 如何停止.Net核心Web API中的自引用循环?,c#,asp.net-core-webapi,C#,Asp.net Core Webapi,我有一些问题,我猜这些问题与使用.NETCoreWebAPI和EntityFrameworkCore的自引用有关。当我添加时,我的Web API开始阻塞。包括一些导航属性 我在旧的Web API中找到了一个解决方案,但我不知道如何为.NET核心Web API实现同样的解决方案(我仍处于早期学习阶段) 较旧的解决方案将其粘贴在Global.asax的应用程序_Start()中: GlobalConfiguration.Configuration.Formatters.JsonFormatter.

我有一些问题,我猜这些问题与使用.NETCoreWebAPI和EntityFrameworkCore的自引用有关。当我添加时,我的Web API开始阻塞。包括一些导航属性

我在旧的Web API中找到了一个解决方案,但我不知道如何为.NET核心Web API实现同样的解决方案(我仍处于早期学习阶段)

较旧的解决方案将其粘贴在Global.asax的应用程序_Start()中:

 GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
我怀疑这是在启动的ConfigureService()方法中处理的,但除此之外我不知道更多


还是有更合适的方法来处理这个问题?

好的。。。我终于找到了一些这方面的参考资料。解决办法是:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );

    ...
}

这是我从ReferenceLoopHandling.Ignore获得的,它“隐藏”问题,而不是解决问题。您真正需要做的是构建层。创建位于实体之上的域对象,并将它们封装在某种服务/业务层中。查找存储库模式并应用它(如果有帮助)。您需要在实体和域对象之间进行映射,这使您有机会适应某种映射器(automapper)和验证层

如果您的域对象和实体完全相同,那么您需要更多地考虑自己在做什么

例如:您的实体是否有软删除?(被删除)国旗?如果是这样,这不一定需要通过web返回到客户机,因此这是一个完美的例子,说明了它们的不同之处


无论哪种方式,答案都不是用JSON覆盖它,而是更改您的体系结构。

如果您使用的是ASP.NET Core 3.0,并且遇到此问题,请安装NuGET软件包:Microsoft.AspNetCore.Mvc.NewtonsoftJson 3.0

要替换新的System.Text.Json(它还没有在Startup.cs中进行引用循环处理),请确保在ConfigureServices中包括:

如果使用最新的.Net Core 3.0方式:

services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
还是老办法:

services.AddMvc(option => option.EnableEndpointRouting = false)
       .AddNewtonsoftJson(options => 
                 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore)
       .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

一般来说,我使用的API对象没有循环(不是直接的EF对象)@BradleyDotNET我同意,将DB映射到以API调用方为中心的wire对象。DB over a wire是软件开发的反模式(讽刺的是,对于这么多“做休息”的人来说,它是一个goto解决方案),它似乎违反了DRY原则,因为我的wire模型看起来与EF填充的模型完全相同。@SailingJudo真正的问题是它们应该吗?通常,API对象可以比关系数据库所需的对象平坦得多。非常感谢。。。这让我发疯。我也有同样的问题。我觉得在转换为json时,默认情况下应该处理这个问题。见奥恩瑟。也许你可以将它添加到你的anwer中。我如何使用System.Text.JSONas做到这一点?我在Text.json中提到过,它还不受支持。如果有人知道如何使用.AddControllersWithViews()lmk进行链接,我就找不到办法了。我一直在
序列化设置
上出错,所以我一直在寻找替换这些选项的方法,但事实证明,我使用的是旧的(?)
AddJsonOptions
,没有意识到我需要用
AddNewtonsoftJson
替换它。一旦我这样做了,我就能够再次使用
序列化设置
,并在升级旧项目时保留旧功能。谢谢你!我花了好几个小时想弄明白。只是好奇,但这有什么理由呢?使用域实体而不是将它们重新创建为DTO(这就是我假设您所说的“实体”)的问题在哪里?有时这更容易(即使使用我使用的存储库模式),特别是如果您有很多域实体,并且这些实体位于您已经想要在客户端上使用的模式中。我想知道“我”做错了什么。域对象通常都有业务逻辑。。例如,它可以由“FirstName”和“姓氏”组成一个属性,如“Display Name”。。DTO希望尽可能“干净”。。部分原因是为了序列化,但也因为它使整个事务更干净,因为调用者只希望看到他们需要操作哪些字段来在线路上来回传递有效对象。根据您的环境,它可能是纯语义的,但域对象和DTO之间有明确的区别