【问题标题】:502 error upload csv file to web api将 csv 文件上传到 web api 时出现 502 错误
【发布时间】:2018-03-08 11:44:29
【问题描述】:

我有一个带有文件上传功能的 Angular5 用户界面。用户点击一个按钮,选择一个文件,该文件被发送到web api(asp.NET Core)方法进行处理。

这适用于较小的文件,但对于较大的文件,请求会超时并出现 502 错误。

我可以看到请求总是在 120 秒时超时。 (注意:我在开发中通过节点托管,在生产中通过 IIS 托管)。

在大文件的情况下,我需要将此超时延长到更大的值。我尝试通过多种方式实现这一目标:

  1. 请求标头 - 角度代码中的请求超时。我使用以下代码尝试设置超时标头值,但它不影响 120 秒:

    export class AuthTokenInterceptor implements HttpInterceptor {
    
    constructor(private authContext: AuthContext) {
    }
    
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const authHeaderValue = this.authContext.getAuthenticationHeaderValue(req.url);
    
        if (authHeaderValue) {
            const authReq = req.clone({  headers:
              req.headers.set('Authorization', authHeaderValue)
                         .set('Timeout', '100000000000000000') });
    
            return next.handle(authReq);
        }
        return next.handle(req);
    }    }
    
  2. web.config - 我尝试将 web.config 文件中的 httpRuntime 超时值设置为以下值(但仍会在 120 秒时超时):

  3. 在 IIS 内 - 我尝试在 IIS 中设置“限制”属性的配置,但仍然在 120 秒时超时(当我在通过节点服务器运行)。

有没有人能够在他们的 Angular(2+) 应用请求中修改这 120 秒?

提前感谢您的任何指点!

注意:为了完整起见,这是我的 asp.net 核心,用于上传的控制器方法:

[HttpPost("Upload")]
public async Task<IActionResult> UploadAsync(IFormFile file)
{
    // Ensure the file has contents before processing.
    if (file == null || file.Length == 0)
        throw new ApiException("Csv file should not be null", HttpStatusCode.BadRequest)
            .AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.BelowMinimumLength, SOURCE); 

    // Ensure the file is not over the allowed limit.
    if (file.Length > (_settings.MaxCsvFileSize * 1024))
        throw new ApiException("Max file size exceeded, limit of " + _settings.MaxCsvFileSize + "mb", HttpStatusCode.BadRequest)
            .AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.ExceedsMaximumLength, SOURCE); 

    // Ensure the file type is csv and content type is correct for the file.
    if (Path.GetExtension(file.FileName) != ".csv" || 
        !Constants.CsvAcceptedContentType.Contains(file.ContentType.ToLower(CultureInfo.InvariantCulture)))
            throw new ApiException("Csv content only accepted").AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.Invalid, SOURCE);

    // Read csv content.
    var content = await file.ReadCsvAsync<OrderCsvResponseDto>() as CsvProcessedResponseDto<OrderCsvResponseDto>;

    await ProcessBulkUpload(content);

    // Return information about the csv file.
    return Ok(content);
}

注意 - 当我通过 IIS Express 运行 web api 时它会超时,我已经使用命令 host 运行它并且它不会超时 - 似乎这可能与某种 IIS 设置有关。由于我使用的是新版本的 ASP.net Core,web api 没有 web.config 文件,但是当我运行这段代码时,它似乎与 IIS Express 没有任何关系:

      var host = new WebHostBuilder()
                .UseStartup<Startup>()
                .UseKestrel(o => {

                    o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10);
                    o.ShutdownTimeout = TimeSpan.FromMinutes(10);
                    o.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(10);

                })
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseApplicationInsights()
                .Build();

【问题讨论】:

  • 你见过这个 - stackoverflow.com/a/38507709/5740031 吗?
  • 谢谢,但这并没有帮助 - 我在 API 端尝试了这个,因为客户端是 Angular,但仍然没有乐趣
  • 如果请求执行时间超过 120 秒,我能够重现 502 错误。正如this answer 建议的那样,我还可以通过将requestTimeout="00:20:00" 添加到web.config 中的aspNetCore 部分来修复它。请重新检查。
  • 您不需要对 UI 透视图进行任何更改?那么只需将其添加到 Web Api web.config 中?
  • 我已经尝试过了,没有任何特定的客户端代码。我相信问题出在服务器端。您可以通过添加一些带有长 Sleep() 的简单 GET 方法并使用浏览器调用它来验证它,而无需 Angular 层。

标签: node.js iis-7.5 angular5 asp.net-core-2.0


【解决方案1】:

我会在此处发布此内容,以防其他人遇到与我相同的问题。事实证明,在 IIS Express(或托管 IIS)中运行,配置设置会覆盖您在代码中拥有的任何内容(可能这是因为 .net Core 的较新版本在项目中没有 web.config 文件 - 我我不确定)。

无论如何,我通过执行以下步骤解决了这个问题:

在任务栏中打开 IIS Express

单击您正在运行的应用程序(并希望延长请求超时)。 单击应用程序会显示应用程序的配置文件。双击打开配置文件。

将以下设置应用于 aspNetCore 部分:

requestTimeout="00:20:00"

例子:

   <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" requestTimeout="00:20:00" stdoutLogEnabled="false" />
      <httpCompression>
        <dynamicCompression>
          <add mimeType="text/event-stream" enabled="false" />
        </dynamicCompression>
      </httpCompression>
    </system.webServer>

就是这样!

注意:我在 PaaS ASE 中托管应用程序 - 所以不能直接在此处配置 IIS。我现在的解决方案是在 api 项目中添加一个 web.config 文件,并在其中应用我的设置。构建过程尊重您已经拥有的 web.config,而不是动态生成一个,它将保留所需的更改。在我的例子中,web.config 看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" requestTimeout="00:20:00" stdoutLogEnabled="false" />
  </system.webServer>
</configuration>

希望这对其他人有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 2021-09-05
    • 2021-06-25
    • 1970-01-01
    • 2017-10-04
    • 2015-09-14
    相关资源
    最近更新 更多