C# API 上正文数据长度大于 100MB 的 HTTP 请求错误 500

问题描述 投票:0回答:2

我们在 C# 中开发了一个 ASP.NET Core 2.0 Web API,通过 Visual Studio 模板创建。

它已经运行多年,我们从未遇到过任何性能问题。直到最近,我们还没有处理过大的 HTTP 请求,所以我们改进了 API 配置以允许大于 2GB 的请求。

我们修改了应用的Web.config如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="2147483647" />
      </requestFiltering>
    </security>
  </system.webServer>
  <system.web.extensions>
   <scripting>
     <webServices>
       <jsonSerialization maxJsonLength="2147483647"></jsonSerialization>
     </webServices>
   </scripting>
  </system.web.extensions>
</configuration>

使用此配置,我们开始能够毫无问题地接收 .NET Web 应用程序默认情况下大于 30MB 的请求,但是,当这些请求超过大约 100 MB 时,应用程序将返回 500 错误。

API由4层组成:

  1. 安全
  2. 控制器
  3. 服务
  4. 资料库

问题是我尝试发送超过 100MB 的数据并且我已经能够验证它们到达第 2 层和第 3 层(第 1 层仅管理用户安全)但是当它们要将数据从第 3 层传递到第 4 层时,应用程序返回 500 错误。

奇怪的是第 3 层和第 4 层是 DLL,它们不是可以配置请求大小限制的 Web 项目。

API 在 Azure 中发布,我们认为这是一个内存问题,但是,通过增加 API 缩放并增加 RAM 和 CPU,同样的问题不断发生。

有没有人遇到过这样的事情?任何可能的解决方案?

提前非常感谢

c# azure asp.net-core-webapi asp.net-core-2.0 http-status-code-500
2个回答
0
投票

除了内容长度之外,您还应该检查请求超时的设置,因为它也可能会在 The

500 - error status code
:

增加请求超时在

.UseKestrel(o => { o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10); })
中的
.Build()
之前添加
Program.cs

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(o => { o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10); })
        .Build();
}

此外,第三方集成可能会超时或限制,具体取决于您存储文件本身的位置和方式。


-1
投票

当你用这种方法上传小文件时它很好。 但是在处理大文件时,您尝试分块上传文件。 以下代码可以作为很好的起点。

[HttpPost]
public ActionResult ReceiveLargeFileInChunks()
{
    // Set the size of each chunk in bytes (e.g. 1 MB)
    int chunkSize = 1024 * 1024;

    // Get the file from the request
    HttpPostedFileBase file = Request.Files[0];

    // Get the total size of the file
    long fileSize = file.ContentLength;

    // Get the file name and extension
    string fileName = Path.GetFileName(file.FileName);
    string fileExtension = Path.GetExtension(fileName);

    // Create a buffer to hold each chunk of data
    byte[] buffer = new byte[chunkSize];

    // Set the total number of bytes received to zero
    long totalBytesReceived = 0;

    // Open a file stream to write the received data to disk
    using (FileStream fileStream = new FileStream(Server.MapPath("~/App_Data/" + fileName), FileMode.Create, FileAccess.Write))
    {
        // Loop until all data has been received
        while (totalBytesReceived < fileSize)
        {
            // Read a chunk of data from the input stream
            int bytesRead = Request.InputStream.Read(buffer, 0, buffer.Length);

            // Write the data to the file stream
            fileStream.Write(buffer, 0, bytesRead);

            // Increment the total number of bytes received
            totalBytesReceived += bytesRead;
        }
    }

    // Return a success message to the client
    return Content("File uploaded successfully.");
}
© www.soinside.com 2019 - 2024. All rights reserved.