502错误将csv文件上传到web api [英] 502 error upload csv file to web api

查看:30
本文介绍了502错误将csv文件上传到web api的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这适用于较小的文件,但对于较大的文件,请求会因 502 错误而超时.

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

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

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

    导出类 AuthTokenInterceptor 实现 HttpInterceptor {构造函数(私有 authContext:AuthContext){}拦截(req: HttpRequest

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

    提前感谢您的指点!

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

    [HttpPost("上传")]公共异步任务上传异步(IFormFile 文件){//在处理之前确保文件有内容.if (file == null || file.Length == 0)throw new ApiException("Csv 文件不能为空", HttpStatusCode.BadRequest).AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.BelowMinimumLength, SOURCE);//确保文件没有超过允许的限制.if (file.Length > (_settings.MaxCsvFileSize * 1024))throw new ApiException("超出最大文件大小,限制" + _settings.MaxCsvFileSize + "mb", HttpStatusCode.BadRequest).AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.ExceedsMaximumLength, SOURCE);//确保文件类型为 csv 并且文件的内容类型正确.if (Path.GetExtension(file.FileName) != ".csv" ||!Constants.CsvAcceptedContentType.Contains(file.ContentType.ToLower(CultureInfo.InvariantCulture)))throw new ApiException("只接受 Csv 内容").AddApiExceptionResponseDetails(ErrorTypeCode.ValidationError, ErrorCode.Invalid, SOURCE);//读取 csv 内容.var content = await file.ReadCsvAsync() as CsvProcessedResponseDto;等待 ProcessBulkUpload(content);//返回有关 csv 文件的信息.返回确定(内容);}

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

     var host = new WebHostBuilder().UseStartup<启动>().UseKestrel(o => {o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10);o.ShutdownTimeout = TimeSpan.FromMinutes(10);o.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(10);}).UseContentRoot(Directory.GetCurrentDirectory()).UseIISIntegration().UseApplicationInsights().建造();

    解决方案

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

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

    在任务栏中打开 IIS Express

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

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

    requestTimeout="00:20:00"

    示例:

     <处理程序><add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/></处理程序><aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" forwardWindowsAuthToken="false" requestTimeout="00:20:00" stdoutLogEnabled="false"/><http压缩><动态压缩><add mimeType="text/event-stream" enabled="false"/></dynamicCompression></httpCompression></system.webServer>

    就是这样!

    注意:我在 PaaS ASE 中托管应用程序 - 因此无法直接在此处配置 IIS.我现在的解决方案是将 web.config 文件添加到 api 项目,并在其中应用我的设置.构建过程尊重您已经获得的 web.config,而不是即时生成一个,它将保留所需的更改.就我而言,web.config 如下所示:

    </system.webServer></配置>

    希望这能帮助其他人!

    I have an Angular5 user interface with a file upload function. The user clicks a button and selects a file and the file is sent to the web api (asp.NET Core) method for processing.

    This works fine with smaller files, but with larger files the request times out with a 502 error.

    I can see the request always timesout at 120 seconds. (NOTE: I am hosting via node in development and via IIS in production).

    In the case of large files I need to extend this timeout to a larger value. I've tried to achieve this in a number of ways:

    1. Request Header - Timeout of request in angular code. I used the following code to try to set the timeout header value but it doesn't effect the 120 seconds:

      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 - I've tried setting the httpRuntime timeout value in the web.config file to the following (but still times out at 120 seconds):

    3. Within IIS - I've tried setting the configuration of the "Limits" property in IIS and again, still times out at 120 seconds (and this has no relevance when I'm running through node server).

    Has anyone been able to modify this 120 seconds in their Angular(2+) app requests?

    Thanks for any pointers in advance!

    NOTE: just for completeness, here's my asp.net core, controller method for uploading:

    [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);
    }
    

    Note - when I run the web api via IIS Express then it times out, I've run it using the command host and it doesn't time out - seem's like this may be related to an IIS setting of sorts. The web api doesn't have a web.config file due to the new version of ASP.net Core I'm using but this piece of code doesn't seem to have any bearing on IIS Express when I run through it:

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

    解决方案

    I will post this here in case anyone else comes across the same problem I was having. It turns out that running in IIS Express (or hosted IIS) that the config setting overrides whatever you have in code (maybe this is because the newer version of .net Core doesn't have a web.config file in the project - I'm not sure).

    Anyway, I worked around this problem by carrying out the following steps:

    Open IIS Express in your taskbar

    Click on the app you are running (and wish to extend the request timeout for). Clicking the app shows the config file of the application. Double click to open the config file.

    Apply the following setting to the aspNetCore section:

    requestTimeout="00:20:00"

    Example:

       <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>
    

    And that's it!

    NOTE: I am hosting the app in PaaS ASE - so cant configure IIS directly here. My solution for this was now to add a web.config file to the api project, and apply my setting within it. The build process honours the web.config you've got already instead of generating one on the fly and it will keep the changes needed. In my case, the web.config looked like this:

    <?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>
    

    Hopefully this helps others!

    这篇关于502错误将csv文件上传到web api的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆