在Asp.Net Core中增加上传文件大小

117

目前,我正在使用Asp.Net Core和MVC6进行工作,需要上传无限制大小的文件。我已经搜索了解决方案,但仍然没有得到实际答案。

我尝试过这个链接

如果有人有任何想法,请帮忙。

谢谢。


我自己仍在努力弄清楚这个问题,尝试了答案中提供的所有解决方案。你们最终能解决这个问题吗? - undefined
14个回答

105

其他答案已经解决了IIS的限制。然而,从ASP.NET Core 2.0版本开始,Kestrel服务器也会实施自己的默认限制。

KestrelServerLimits.cs的Github页面

请求体大小限制和解决方案的公告(下面引用)

MVC指南

如果您想要更改特定MVC操作或控制器的最大请求体大小限制,您可以使用RequestSizeLimit属性。下面的示例允许MyAction接受多达100,000,000字节的请求体。

[HttpPost]
[RequestSizeLimit(100_000_000)]
public IActionResult MyAction([FromBody] MyViewModel data)
{

[DisableRequestSizeLimit]可以用来使请求大小无限制。这有效地恢复了2.0.0之前的行为,只针对所指定的操作或控制器。

通用中间件说明

如果请求不是由MVC动作处理,仍然可以使用IHttpMaxRequestBodySizeFeature在每个请求上修改限制。例如:

app.Run(async context =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize = 100_000_000;

MaxRequestBodySize 是一个可空的长整型。将其设置为 null 将禁用限制,就像 MVC 的 [DisableRequestSizeLimit] 一样。

如果应用程序还没有开始读取请求,则只能在请求之前配置限制;否则会抛出异常。有一个 IsReadOnly 属性,告诉你 MaxRequestBodySize 属性是否处于只读状态,这意味着现在配置限制已经太晚了。

全局配置说明

如果您想全局修改最大请求体大小,则可以通过修改 UseKestrelUseHttpSys 的回调函数中的 MaxRequestBodySize 属性来完成。在这两种情况下,MaxRequestBodySize 都是可空的长整型。例如:

.UseKestrel(options =>
{
    options.Limits.MaxRequestBodySize = null;
或者
.UseHttpSys(options =>
{
    options.MaxRequestBodySize = 100_000_000;

你或其他人使用这个程序成功上传的最大文件是多少?我只是好奇,因为我正在开发一个需要进行大文件上传以实现安全通信的项目。 - Radar5000
1
我已经上传了10 GB的文件。我认为你只会受到最大服务器超时设置的限制,或者是内存/文件存储限制,这取决于你如何流式传输/存储文件。 - Matthew Steven Monkan
5
在我的情况下,仅使用 DisableRequestSizeLimit 属性是不够的。我还需要使用 RequestFormLimits。像这样: [HttpPost("upload"), DisableRequestSizeLimit, RequestFormLimits(MultipartBodyLengthLimit = Int32.MaxValue, ValueLengthLimit = Int32.MaxValue)] - Xav987
4
Mathew和@Xav987,你们在使用IFormFile时是采用模型绑定还是通过这里提到的冗长方式来处理大文件:https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.1 - Mark Redman
@Xav987:谢谢,我之前一直在看冗长的方法,但通过设置两个属性避免了那种情况。 - Mark Redman
对于 ASP.NET Core 版本 >= 2.0:在 ASP.NET Core 版本 >= 2.0 中上传大小超过 30.0 MB 的文件 - TanvirArjel

51

当您上传任何超过30MB的文件时,您可能会收到404.13 HTTP状态代码。如果您在IIS中运行ASP.Net Core应用程序,则IIS管道将在请求到达应用程序之前拦截您的请求。

请更新您的web.config文件:

<system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
    <!-- Add this section for file size... -->
    <security>
      <requestFiltering>
        <!-- Measured in Bytes -->
        <requestLimits maxAllowedContentLength="1073741824" />  <!-- 1 GB-->
      </requestFiltering>
    </security>
  </system.webServer>

之前的ASP.Net应用程序也需要这个部分,但在Core中不再需要,因为您的请求已由中间件处理:

  <system.web>
    <!-- Measured in kilobytes -->
    <httpRuntime maxRequestLength="1048576" />
  </system.web>

1
你可能是想说30MB,而不是GB。 - jao
9
如果你像我从来不会做的那样,盲目地复制/粘贴上面的内容,请不要忘记这需要嵌套在<configuration>元素中。 - JackMorrissey

48

也许我来得有点晚,但是这里提供了上传超过30.0 MB文件的完整解决方案,适用于ASP.NET Core版本>=2.0:

您需要执行以下三个步骤:

1. IIS内容长度限制

默认请求限制(maxAllowedContentLength)为30,000,000字节,大约为28.6 MB。在web.config文件中自定义限制:

<system.webServer>
    <security>
        <requestFiltering>
            <!-- Handle requests up to 1 GB -->
            <requestLimits maxAllowedContentLength="1073741824" />
        </requestFiltering>
    </security>
</system.webServer>

注意:若没有运行该应用程序,IIS将无法工作。

2. ASP.NET Core请求长度限制

对于在IIS上运行的应用程序:

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

对于在Kestrel上运行的应用程序:

services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.MaxRequestBodySize = int.MaxValue; // if don't set default value is: 30 MB
});

3. Form's MultipartBodyLengthLimit

services.Configure<FormOptions>(options =>
{
    options.ValueLengthLimit = int.MaxValue;
    options.MultipartBodyLengthLimit = int.MaxValue; // if don't set default value is: 128 MB
    options.MultipartHeadersLengthLimit = int.MaxValue;
});

添加以上所有选项将解决与上传大小超过30.0 MB的文件相关的问题。


我已经完成了上述提到的三个步骤,但仍然遇到CORS问题。如果您能添加一些调试内容,那将对某些人有所帮助。我刚刚跳过了这个服务.Configure<IISServerOptions>(options =>,因为我正在使用Web API 2.1 C#。 - Var
对于Kestrel,我不得不设置 services.Configure<KestrelServerOptions>(options => options.Limits.MaxRequestBodySize = <my value>); - Peheje
这对于JSON POST请求体也适用吗? - JustAMartin

32
在由Visual Studio 2017创建的ASP.NET Core 1.1项目中,如果您想增加上传文件的大小,则需要自己创建web.config文件,并添加以下内容:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <security>
      <requestFiltering>
        <!-- 1 GB -->
        <requestLimits maxAllowedContentLength="1073741824" />
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

在 Startup.cs 文件中,添加以下内容:

public void ConfigureServices(IServiceCollection services)
{
  services.Configure<FormOptions>(x =>
  {
      x.ValueLengthLimit = int.MaxValue;
      x.MultipartBodyLengthLimit = int.MaxValue;
      x.MultipartHeadersLengthLimit = int.MaxValue;
  });

  services.AddMvc();
}

26

在您的 startup.cs 中配置 FormsOptions Http 功能:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<FormOptions>(o =>  // currently all set to max, configure it to your needs!
    {
        o.ValueLengthLimit = int.MaxValue;
        o.MultipartBodyLengthLimit = long.MaxValue; // <-- !!! long.MaxValue
        o.MultipartBoundaryLengthLimit = int.MaxValue;
        o.MultipartHeadersCountLimit = int.MaxValue;
        o.MultipartHeadersLengthLimit = int.MaxValue;
    });
}
使用IHttpMaxRequestBodySizeFeature Http 功能来配置MaxRequestBodySize
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize = null; // unlimited I guess
        await next.Invoke();
    });
}
(Kestrel 是 .NET Core 平台上的一个轻量级 Web 服务器)
public static IHostBuilder CreateHostBuilder(string[] args) =>
                    Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>().UseKestrel(o => o.Limits.MaxRequestBodySize = null);
                    });
IIS --> web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <!-- ~ 2GB -->
    <httpRuntime maxRequestLength="2147483647" /> // kbytes
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <!-- ~ 4GB -->
        <requestLimits maxAllowedContentLength="4294967295" /> // bytes
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

Http.sys:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>().UseHttpSys(options =>
            {
                options.MaxRequestBodySize = null;
            });
        });
如果您想上传一个非常大的文件,可能是几GB大小,并且希望将其缓冲到服务器上的`MemoryStream`中,您将收到错误消息 `Stream was too long`,因为`MemoryStream`的容量是`int.MaxValue`。 您需要实现自己的自定义`MemoryStream`类。 但无论如何,缓冲这样大的文件都没有意义。

10

使用 Visual Studio 2022 (v 17.1.6) 和 .net core 6,我在 Program.cs 类中无需更改任何内容。只需要在我的控制器方法中添加这两个属性(除了 [HttpPost] 和 [Route]),就可以在本地运行时接受100MB的上传:

[RequestSizeLimit(100 * 1024 * 1024)]
[RequestFormLimits(MultipartBodyLengthLimit = 100 * 1024 * 1024)]

当传递到Docker化的环境中时,它会返回错误请求:S。 - Enrique Mingyar Torrez Hinojos
我相信你已经尝试过了,但是如果你在docker之外运行相同的代码和配置,它是否允许更大的上传?我对docker的经验非常少,但我想象它不会涉及到限制单个入站POST所需的级别,对吧? - MPowerGuy

10

在我的情况下,我需要仅针对单个页面增加文件上传大小限制。

文件上传大小限制是一项安全功能,关闭或在全局范围内增加它通常不是一个好主意。您不希望某些脚本小子通过上传极大的文件来DOS攻击您的登录页面。文件上传限制可以为此提供一定的保护,因此关闭或在全局范围内增加它并不总是一个好主意。

因此,要仅增加单个页面的限制而非全局性的话:

(我使用ASP.NET MVC Core 3.1和IIS,如果使用Linux则配置会有所不同)

1. 添加web.config

否则,IIS(或者如果在Visual Studio中调试,则是IIS Express)将在请求甚至到达您的代码之前阻止该请求,并显示“HTTP错误413.1 - 请求实体过大”的错误。

请注意“location”标记,它将上传限制限制为特定页面

您还需要“handlers”标记,否则当浏览到该路径时,您将收到HTTP 404错误

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="SomeController/Upload">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <security>
        <requestFiltering>
          <!--unit is bytes => 500 Mb-->
          <requestLimits maxAllowedContentLength="524288000" />
        </requestFiltering>
      </security>
    </system.webServer>
  </location>
</configuration>
  1. Next you will need to add the RequestSizeLimit attribute to your controller action, since Kestrel has its own limits too. (you can instead do it via middleware as per other answers if you prefer)

     [HttpPost]
     [RequestSizeLimit(500 * 1024 * 1024)]       //unit is bytes => 500Mb
     public IActionResult Upload(SomeViewModel model)
     {
         //blah blah
     }
    

为了完整性(如果使用MVC),您的视图和视图模型可能如下所示:

视图

<form method="post" enctype="multipart/form-data" asp-controller="SomeController" asp-action="Upload">
    <input type="file" name="@Model.File" />
</form>

视图模型

public class SomeViewModel
{
    public IFormFile File { get; set; }
}

如果您通过表单提交上传的文件大于128Mb,您也可能会遇到此错误

InvalidDataException: 多部分正文长度限制超过了134217728。

因此,在您的控制器操作中,您可以添加 RequestFormLimits 属性

 [HttpPost]
 [RequestSizeLimit(500 * 1024 * 1024)]       //unit is bytes => 500Mb
 [RequestFormLimits(MultipartBodyLengthLimit = 500 * 1024 * 1024)]
 public IActionResult Upload(SomeViewModel model)
 {
     //blah blah
 }

9

使用web.config可能会影响.NET Core的架构,并且在Linux或Mac上部署解决方案时可能会遇到问题。

更好的方法是使用Startup.cs来配置此设置:例如:

services.Configure<FormOptions>(x =>
{
    x.ValueLengthLimit = int.MaxValue;
    x.MultipartBodyLengthLimit = int.MaxValue; // In case of multipart
});

这里有一个更正:

你还需要添加 web.config 文件,因为当请求到达 IIS 时,它会搜索 web.config 并检查最大上传长度。例如:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <security>
     <requestFiltering>
    <!-- 1 GB -->
     <requestLimits maxAllowedContentLength="1073741824" />
  </requestFiltering>
</security>

4
  1. In your web.config:

    <system.webServer>
      <security>
        <requestFiltering>
          <requestLimits maxAllowedContentLength="2147483648" />
        </requestFiltering>
      </security>
    </system.webServer>
    
  2. Manually edit the ApplicationHost.config file:

    1. Click Start. In the Start Search box, type Notepad. Right-click Notepad, and then click "Run as administrator".
    2. On the File menu, click Open. In the File name box, type "%windir%\system32\inetsrv\config\applicationhost.config", and then click Open.
    3. In the ApplicationHost.config file, locate the <requestLimits> node.
    4. Remove the maxAllowedContentLength property. Or, add a value that matches the size of the Content-Length header that the client sends as part of the request. By default, the value of the maxAllowedContentLength property is 30000000.

      enter image description here

    5. Save the ApplicationHost.config file.


4

为了其他像我这样不幸的人,我将此补充说明:

Startup.cs中:

services.Configure<FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = 60000000;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接