.Net Core 2.1 IIS部署multipart上传POST报413 IIS Express正常
问题背景
- 技术栈:前端为Angular SPA单页应用,后端基于.NET Core 2.1框架开发,以Self-Contained(独立部署)模式发布为win-x64版本,托管在IIS上,应用程序池配置为无托管代码/集成模式。
- 异常现象:开发环境使用IIS Express调试时,multipart/form-data类型的POST上传接口(同时提交表单数据与blob/图片文件)可正常运行;部署到预发布IIS环境后,接口固定返回
413 Request entity too large(请求实体过大)错误,且该异常仅在Firefox浏览器中触发,清除浏览器缓存后问题仍复现。 - 当前已完成的配置:
- web.config配置如下:
<configuration> <location path="." inheritInChildApplications="false"> <system.web> <httpRuntime maxRequestLength="1048576" /> </system.web> <system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="1073741824" /> </requestFiltering> </security> <handlers> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" /> </handlers> <aspNetCore processPath=".\my.app.exe" stdoutLogEnabled="false" stdoutLogFile=".\log\path" /> </system.webServer> </location> </configuration>
- 对应接口控制器已添加请求大小限制相关特性:
[HttpPost] [DisableRequestSizeLimit] [RequestFormLimits(MultipartBodyLengthLimit = int.MaxValue, ValueLengthLimit = int.MaxValue)] [RequestSizeLimit(int.MaxValue)] [Route("my/route")] public ActionResult MyHandler()
- Program.cs中已配置Kestrel服务请求体大小上限:
.UseKestrel(options => { options.Limits.MaxRequestBodySize = 104857600; // 100MB } )
排查方向与解决方案
第一层:排查IIS层配置冲突与模块干扰
- 删除web.config中
system.web节点下的httpRuntime配置:该配置仅对传统System.Web托管的.NET Framework应用生效,无托管代码模式下IIS不会加载对应模块,保留该配置无实际作用,反而会干扰配置排查。 - 调整请求大小限制的配置层级:当前
requestLimits maxAllowedContentLength配置写在location子节点下,部分IIS版本的AspNetCoreModule在转发请求前,会优先读取站点根级别的请求过滤配置,而非location节点内的配置。可直接通过IIS管理器的「请求筛选」功能,在站点级别设置允许的最大内容长度为1073741824(即1GB),配置完成后执行iisreset重启IIS生效。 - 排查IIS加载的第三方/内置模块干扰:动态压缩模块、URL重写模块、服务器上安装的WAF/安全防护软件,对multipart/form-data的解析逻辑存在浏览器兼容差异——Firefox发送的multipart请求会自动携带charset参数、blob文件的元数据格式和Chrome/Edge存在区别,可能触发模块的长度校验逻辑误判。可临时逐一禁用上述模块,测试问题是否复现。
- 确认413错误的返回来源:开启web.config中aspNetCore节点的stdout日志(设置
stdoutLogEnabled="true"),发起请求后查看日志:如果日志中无对应请求记录,说明413是IIS层直接返回;如果日志中存在RequestBodyTooLarge类的异常堆栈,说明错误是Kestrel/应用层返回,可缩小排查范围。
第二层:排查前端请求构造的浏览器差异
- 抓包对比Firefox与正常浏览器的请求差异:重点核对
Content-Length实际值、Content-Type头是否正确携带multipart分隔符。Firefox通过FormData追加无文件名的blob对象时,会自动附加额外的元数据字段,可能导致实际请求体大小比其他浏览器大,刚好超过某一层配置的大小阈值。 - 检查Angular全局HTTP拦截器逻辑:部分自定义拦截器在Firefox下会重复序列化FormData内容,或给请求追加额外的鉴权、日志字段,导致请求体异常膨胀触发限制。
第三层:排查应用层配置冲突
- 移除控制器上冲突的特性配置:
[DisableRequestSizeLimit]的作用是完全放开Kestrel请求大小限制,同时添加[RequestSizeLimit(int.MaxValue)]会重新覆盖前者的配置,两者保留其一即可,避免优先级冲突导致特性不生效。 - 检查Startup.cs中的全局Form配置:除了接口上的
[RequestFormLimits]特性,确认ConfigureServices方法中没有通过services.Configure<FormOptions>()全局配置更低的MultipartBodyLengthLimit阈值,.NET Core 2.1中multipart请求体默认阈值为28.6MB,若接口特性因路由、优先级问题未生效,会触发默认限制。
内容的提问来源于stack exchange,提问作者GeofoxCoding
相关产品推荐
相关产品推荐

