.NET Core Web api 仅在 IIS 上调用 ERR_CONNECTION_RESET - 其他调用正常

Posted

技术标签:

【中文标题】.NET Core Web api 仅在 IIS 上调用 ERR_CONNECTION_RESET - 其他调用正常【英文标题】:.NET Core Web api call ERR_CONNECTION_RESET only on IIS - other calls working 【发布时间】:2017-01-05 16:13:50 【问题描述】:

我现在完全不知所措......

我有一个 .NET Core Web 应用程序,并且在本地运行一切正常。有许多 WebAPI 端点,同样都按预期使用 GET 并正确返回 JSON。

当我发布到 IIS 时,只有一个端点停止工作并抛出 (failed) net:ERR_CONNECTION_RESET(在 Chrome 中 - 其他浏览器会抛出它们自己的错误)。

独特之处在于所有其他 Web API 调用都在工作,都在相同的环境中并调用相同的数据库,使用相同的上下文和 EF 数据服务。

我想不通的是如何将详细的日志从 Kestrel 获取到其他一些日志记录服务中,无论是 Windows 事件查看器、文本文件、电子邮件还是其他任何东西!我没有使用太多的日志中间件,目的是在我们接近生产时将其连接起来。

使用 .NET core Kestrel Web 服务器在 Windows 2012 R2 上的 IIS 8 中尝试解决此问题的最佳方法是什么?

【问题讨论】:

那么你的问题是什么? 对我来说,最终返回的对象有一个循环引用,即Quotes -> SiteSite -> List<Quote>,所以JSON 解析器抛出了一个错误——但仅限于 prod 环境。我更改了方法以返回一个没有返回引用的更简单的模型,并且它起作用了 谢谢,对我来说,导致错误的是(在线)数据库数据的差异。 是数据序列化导致的吗?因为它的核心将是同样的问题。 【参考方案1】:

我遇到了类似的问题。我正在使用 Entity Framework Core 1.1,它不允许延迟加载。我的错误是由多对多关系中的对象图循环引起的。

由于 EFCore 1.1 不支持开箱即用的多对多,我的模型有循环引用。我的 JSON 序列化程序在尝试序列化从我的控制器类返回的数据时陷入了无限循环。

如果您有这个问题并且其他解决方案都不起作用,我建议您更改您的 Startup.cs 文件 ConfigureServices() 方法。 services.AddMvc(); 行应改为:

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

【讨论】:

如果这个答案确实为您解决了问题,请检查导致问题的方法是否返回了正确类型的对象(例如,某种简单的 DTO,而不是 DbSet 本身!)。【参考方案2】:

只需编辑您的 web.config 并将 stdoutLogEnabled="true" 设置为 true,并设置将写入日志文件的路径。

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <!--
    Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
  -->

  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
  </system.webServer>
</configuration>

但是您至少需要启用控制台记录器,因为它基本上会将控制台输出变为文件。

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)

    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
    ...

“Logging”部分在appsettings.json中配置,如

  "Logging": 
    "IncludeScopes": false,
    "LogLevel": 
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    
  

【讨论】:

.\logs\stdout 路径是根目录然后logs\stdout?这会记录所有错误? 是的,取决于您在AddConsole 中配置的内容。您也可以使用AddDebug,它将这些内容记录到 Visual Studio 的输出选项卡中(当然,仅在调试期间,意味着在附加调试器时) @RemarlLima - 看我的回答,loggerFactory.AddConsole(LogLevel.Trace);将向您显示来自 Kestrel 的所有记录消息,而不仅仅是错误 使用 IConfiguration 覆盖,您可以过滤它并禁用来自您不感兴趣的命名空间的消息【参考方案3】:

您可以使用内置的日志记录中间件来记录 Kestrel。确保通过 stdoutLogEnabled 在 web.config 中启用日志记录,如下所示:

<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false">

您的 startup.cs 包含以下代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

    loggerFactory.AddConsole(LogLevel.Trace);

【讨论】:

【参考方案4】:

编辑 Startup.cs 并将此:services.AddMvc() 替换为:

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

【讨论】:

【参考方案5】:

我在 startup.cs 中添加了以下代码并且它工作正常。

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

我在 Entity Framework Core(父子关系)中使用自引用表。

【讨论】:

【参考方案6】:

我知道这已被标记为已回答,但以上均不适合我。对我来说,解决方案是将 web 项目从 dotnet core 2.1 更新到 2.2,并同时更新 dotnet core SDK。

【讨论】:

以上是关于.NET Core Web api 仅在 IIS 上调用 ERR_CONNECTION_RESET - 其他调用正常的主要内容,如果未能解决你的问题,请参考以下文章

仅在 IIS 部署后的 Asp.net Web api 异常:名为“HelpPage_Default”的路由已在路由集合中

无法让 ASP.NET Core Web API 与 IIS 一起使用 [关闭]

将 asp.net core web api 部署到 IIS 7.5 时出现 500 错误

无法在 IIS Express 中运行 ASP.NET Core Web API 项目

仅在一个 .Net Core 2.0 Web API 控制器上出现 CORS 错误

.NET Core - 在 IIS 上使用 Windows 身份验证从 MVC 应用程序调用 Web API 导致 HttpRequestException 401(未经授权)状态代码