在 Asp.Net 核心中增加上传文件的大小

Posted

技术标签:

【中文标题】在 Asp.Net 核心中增加上传文件的大小【英文标题】:Increase upload file size in Asp.Net core 【发布时间】:2016-12-06 12:06:33 【问题描述】:

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

I have tried this link

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

谢谢。

【问题讨论】:

【参考方案1】:

其他答案解决了 IIS 限制。但是,从 ASP.NET Core 2.0 开始,Kestrel 服务器也施加了自己的默认限制。

Github of KestrelServerLimits.cs

Announcement of request body size limit and solution (quoted below)

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 在这两种情况下都是可以为空的 long。例如:

.UseKestrel(options =>

    options.Limits.MaxRequestBodySize = null;

.UseHttpSys(options =>

    options.MaxRequestBodySize = 100_000_000;

【讨论】:

您或其他人能够成功上传的最大文件是多少?我只是好奇,因为我正在开展一个需要大量上传以实现安全通信的项目。 我上传了 10 GB 的文件。我认为您只会受到达到最大服务器超时设置或达到内存/文件存储限制的限制,具体取决于您流式传输/存储文件的方式。 就我而言,DisableRequestSizeLimit 属性还不够。我也必须使用RequestFormLimits。像这样:[HttpPost("upload"), DisableRequestSizeLimit, RequestFormLimits(MultipartBodyLengthLimit = Int32.MaxValue, ValueLengthLimit = Int32.MaxValue)] Mathew & @Xav987 你是使用 IFormFile 的模型绑定还是这里提到的大文件的冗长方法:docs.microsoft.com/en-us/aspnet/core/mvc/models/… @Xav987:谢谢,我一直在寻找冗长的方法,但通过设置两个属性来避免这种情况。【参考方案2】:

当您上传任何超过 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>

【讨论】:

您的意思可能是 30MB,而不是 GB 如果你盲目地复制/粘贴上面的内容, 就像我永远不会那样,,不要忘记这需要嵌套在&lt;configuration&gt; 元素中。 blogs.msdn.microsoft.com/azureossds/2016/06/15/…【参考方案3】:

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

【讨论】:

【参考方案4】:

也许我来晚了,但这里是在 ASP.NET Core 版本 >=2.0 中上传大小超过 30.0 MB 的文件的完整解决方案:

你需要做以下三个步骤:

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.表单的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 的文件上传相关的问题。

【讨论】:

我完成了上面提到的所有 3 个步骤,但我仍然遇到 CORS 问题,如果您可以添加一些调试内容,那么它将对某人有所帮助。 - 我刚刚跳过了这个 services.Configure(options => 因为我正在使用 web api 2.1 c# 对于 Kestrel 我必须设置 services.Configure&lt;KestrelServerOptions&gt;(options =&gt; options.Limits.MaxRequestBodySize = &lt;my value&gt;);【参考方案5】:

在你的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();
    );


红隼

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的容量是@987654333 @。

您应该实现自己的自定义MemoryStream 类。 但无论如何,缓冲这么大的文件是没有意义的。

【讨论】:

【参考方案6】:

使用 web.config 可能会损害 .NET 核心的体系结构,并且在 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 并检查 maxupload 长度:示例:

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

【讨论】:

【参考方案7】:

    在您的 web.config 中:

    <system.webServer>
      <security>
        <requestFiltering>
          <requestLimits maxAllowedContentLength="2147483648" />
        </requestFiltering>
      </security>
    </system.webServer>
    

    手动编辑 ApplicationHost.config 文件:

      单击开始。在“开始搜索”框中,键入记事本。右键单击记事本,然后单击“以管理员身份运行”。 在“文件”菜单上,单击“打开”。在“文件名”框中,键入“%windir%\system32\inetsrv\config\applicationhost.config”,然后单击“打开”。 在ApplicationHost.config 文件中,找到&lt;requestLimits&gt; 节点。

      删除maxAllowedContentLength 属性。或者,添加一个与客户端作为请求的一部分发送的 Content-Length 标头的大小相匹配的值。默认情况下,maxAllowedContentLength 属性的值为 30000000。

      保存ApplicationHost.config 文件。

【讨论】:

【参考方案8】:

为了完整起见,我会为其他像我这样的不幸的小伙子添加这个,Source

Startup.cs:

services.Configure<FormOptions>(options =>

    options.MultipartBodyLengthLimit = 60000000;
);

【讨论】:

【参考方案9】:

就我而言,我需要增加文件上传大小限制,但仅限于单个页面。

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

因此,增加单个页面而不是全局的限制:

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

1.添加 web.config

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

注意“位置”标签,它将上传限制限制在特定页面

您还需要“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>

    接下来,您需要将 RequestSizeLimit 属性添加到控制器操作中,因为 Kestrel 也有自己的限制。 (如果您愿意,可以根据其他答案通过中间件来实现)

     [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
 

【讨论】:

以上是关于在 Asp.Net 核心中增加上传文件的大小的主要内容,如果未能解决你的问题,请参考以下文章

增加在 Azure 上运行的 Dockerized ASP.NET Core 站点的最大上传大小限制?

如何在 ASP.NET C# 中上传 10GB+ 大小的文件

在 ASP.NET 4 中上传之前如何检查 .xls 文件大小?

在 asp.net 核心客户端中使用 ajax 上传文件类型

如果asp.net mvc3中的大小超过4mb,则无法上传文件[重复]

ASP.NET 图像上传与调整大小