Razor页面大文件上传导致400 Bad Request错误。

huangapple go评论87阅读模式
英文:

Razor Page Large File Upload resulting in 400 Bad Request

问题

我有一个用于上传文件的剃刀页面。我将最大上传大小设置为4GB,但当我上传大于2GB的文件时,出现400 Bad Request错误。我已经添加了互联网上可以找到的所有可能有助于最大上传大小的内容。有一段时间我以为错误已经消失了,但后来它又出现了,代码没有任何变化。

网站托管在IIS上。

有人知道可能是什么问题吗?我将包括所有与上传大小相关的代码。

附注:当我上传大于2GB但小于4GB的文件时,出现400 Bad Request错误。
当我上传大于4GB的文件时,出现413 Request Entity Too Large错误。

我在我的program.cs文件中有以下设置:

builder.Services.Configure<FormOptions>(o =>
{
    o.ValueLengthLimit = int.MaxValue;
    o.MultipartBodyLengthLimit = int.MaxValue;
    o.MultipartBoundaryLengthLimit = int.MaxValue;
    o.MultipartHeadersCountLimit = int.MaxValue;
    o.MultipartHeadersLengthLimit = int.MaxValue;
    o.BufferBodyLengthLimit = int.MaxValue;
    o.BufferBody = true;
    o.ValueCountLimit = int.MaxValue;
});

builder.Services.Configure<IISServerOptions>(options =>
{
    options.MaxRequestBodySize = int.MaxValue;
});

builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.MaxRequestBodySize = int.MaxValue;
});

builder.WebHost.ConfigureKestrel(c =>
{
    c.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(100);
});

我在我的web.config文件中有以下设置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <!-- 大约2GB -->
    <httpRuntime maxRequestLength="419430412" executionTimeout="3600" /> <!-- kbytes -->
    <globalization 
           requestEncoding="utf-8"
           responseEncoding="utf-8"
        />
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <!-- 大约4GB -->
        <requestLimits maxAllowedContentLength="4294967295" /> <!-- bytes -->
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

这是我的上传代码:

[HttpPost]
[RequestFormLimits(MultipartBodyLengthLimit = 4294967295)]
[RequestSizeLimit(4294967295)]
public async Task<IActionResult> OnPostAsync()
{
    var files = Request.Form.Files;

    // 用于进度条
    var uploads = Path.Combine(_environment.WebRootPath, "uploads");
    var totalBytes = files.Sum(f => f.Length);

    //long bytesUploaded = 0;
    //var progressHandler = new ProgressHandler(_httpContextAccessor);

    // 文件夹名称
    var folderName = DateTime.Now.ToString("yyyy-MM-dd-HHmmss") + " - " + HttpContext.Session.GetString("selectedResp");
    var folderPath = Path.Combine(@"C:\UploadTool\Uploads", folderName);

    if (!Directory.Exists(folderPath))
    {
        Directory.CreateDirectory(folderPath);

        if (files.Count == 0)
        {
            return BadRequest("未选择文件。");
        }

        foreach (var file in files)
        {
            var filePath = Path.Combine(folderPath, file.FileName);
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }
        }
    } 
    else
    {
        //ModelState.AddModelError(string.Empty, "文件夹已经存在!");
    }

    return RedirectToPage("Upload");
}
英文:

I have a razor page for uploading files. I've set the maximum upload size to 4GB, but when I upload something larger than 2 GB I get an 400 Bad Request Error. I've added everything I found on the internet, that might help with the maximum upload size. At one point I thought the error was gone, but then it came back, with nothing changed in the code.
The Website is hosted on an IIS.

Has someone a hint what it might be? I'll include all upload size related code I've got.

Sidenote: When I upload a file > 2GB but < 4GB i get an 400 Bad Request Error.
When I upload a file larger than 4GB I get an 413 Request Entity Too Large Error.

I have these settings in my program.cs:

builder.Services.Configure&lt;FormOptions&gt;(o =&gt;
{
    o.ValueLengthLimit = int.MaxValue;
    o.MultipartBodyLengthLimit = int.MaxValue;
    o.MultipartBoundaryLengthLimit = int.MaxValue;
    o.MultipartHeadersCountLimit = int.MaxValue;
    o.MultipartHeadersLengthLimit = int.MaxValue;
    o.BufferBodyLengthLimit = int.MaxValue;
    o.BufferBody = true;
    o.ValueCountLimit = int.MaxValue;
});

builder.Services.Configure&lt;IISServerOptions&gt;(options =&gt;
{
    options.MaxRequestBodySize = int.MaxValue;
});

builder.Services.Configure&lt;KestrelServerOptions&gt;(options =&gt;
{
    options.Limits.MaxRequestBodySize = int.MaxValue;
});

builder.WebHost.ConfigureKestrel(c =&gt;
{
    c.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(100);
});

These settings in my web.config:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;configuration&gt;
  &lt;system.web&gt;
    &lt;!-- ~ 2GB --&gt;
    &lt;httpRuntime maxRequestLength=&quot;419430412&quot; executionTimeout=&quot;3600&quot; /&gt; // kbytes
    &lt;globalization 
           requestEncoding=&quot;utf-8&quot;
           responseEncoding=&quot;utf-8&quot;
        /&gt;
  &lt;/system.web&gt;
  &lt;system.webServer&gt;
    &lt;security&gt;
      &lt;requestFiltering&gt;
        &lt;!-- ~ 4GB --&gt;
        &lt;requestLimits maxAllowedContentLength=&quot;4294967295&quot; /&gt; // bytes
      &lt;/requestFiltering&gt;
    &lt;/security&gt;
  &lt;/system.webServer&gt;
&lt;/configuration&gt;

And this is the upload code:

	[HttpPost]
    [RequestFormLimits(MultipartBodyLengthLimit = 4294967295)]
    [RequestSizeLimit(4294967295)]
    public async Task&lt;IActionResult&gt; OnPostAsync()
    {
        var files = Request.Form.Files;

        // F&#252;r Progress Bar
        var uploads = Path.Combine(_environment.WebRootPath, &quot;uploads&quot;);
        var totalBytes = files.Sum(f =&gt; f.Length);

        //long bytesUploaded = 0;
        //var progressHandler = new ProgressHandler(_httpContextAccessor);

        // Folder Name 
        var folderName = DateTime.Now.ToString(&quot;yyyy-MM-dd-HHmmss&quot;) + &quot; - &quot; + HttpContext.Session.GetString(&quot;selectedResp&quot;);
        var folderPath = Path.Combine(@&quot;C:\UploadTool\Uploads&quot;, folderName);

        if (!Directory.Exists(folderPath))
        {
            Directory.CreateDirectory(folderPath);

            if (files.Count == 0)
            {
                return BadRequest(&quot;No files selected.&quot;);
            }

            foreach (var file in files)
            {
                var filePath = Path.Combine(folderPath, file.FileName);
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }
            }

        } 
        else
        {
            //ModelState.AddModelError(string.Empty, &quot;Folder already exists!&quot;);
        }

        return RedirectToPage(&quot;Upload&quot;);
    }

答案1

得分: 1

这解决了问题。感谢 @pcalkins

builder.Services.Configure<FormOptions>(o =>
{
    o.ValueLengthLimit = int.MaxValue;
    o.MultipartBodyLengthLimit = 4L * 1024L * 1024L * 1024L;
    o.MultipartBoundaryLengthLimit = int.MaxValue;
    o.MultipartHeadersCountLimit = int.MaxValue;
    o.MultipartHeadersLengthLimit = int.MaxValue;
    o.BufferBodyLengthLimit = 4L * 1024L * 1024L * 1024L;
    o.BufferBody = true;
    o.ValueCountLimit = int.MaxValue;
});

builder.Services.Configure<IISServerOptions>(options =>
{
    options.MaxRequestBodySize = Int64.MaxValue;
});

builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.MaxRequestBodySize = Int64.MaxValue;
});
英文:

This fixed the problem. Thanks to @pcalkins

builder.Services.Configure&lt;FormOptions&gt;(o =&gt;
{
    o.ValueLengthLimit = int.MaxValue;
    o.MultipartBodyLengthLimit = 4L * 1024L * 1024L * 1024L;
    o.MultipartBoundaryLengthLimit = int.MaxValue;
    o.MultipartHeadersCountLimit = int.MaxValue;
    o.MultipartHeadersLengthLimit = int.MaxValue;
    o.BufferBodyLengthLimit = 4L * 1024L * 1024L * 1024L;
    o.BufferBody = true;
    o.ValueCountLimit = int.MaxValue;
});

builder.Services.Configure&lt;IISServerOptions&gt;(options =&gt;
{
    options.MaxRequestBodySize = Int64.MaxValue;
});

builder.Services.Configure&lt;KestrelServerOptions&gt;(options =&gt;
{
    options.Limits.MaxRequestBodySize = Int64.MaxValue;
});

huangapple
  • 本文由 发表于 2023年8月10日 15:46:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76873615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定