• .NET Core使用Base64上传附件超过4M无法上传的问题
  • 发布于 2个月前
  • 282 热度
    0 评论
  • 顾及谁
  • 24 粉丝 32 篇博客
  •   
使用 HTTP 协议上传文件的标准做法是:使用 multipart/form-data 。但有时为了实现简单且要上传的文件不会太大,仍然会采用 application/x-www-form-urlencoded 上传文件,这就需要在上传前对二进制文件进行编码,比如使用 Base64 。
public async Task<IActionResult> SubmitImage(int id, [FromForm(Name = "image")] string image)
{
    // 堆代码 duidaima.com
    if (string.IsNullOrWhiteSpace(image)) throw new UserFriendlyException("图片不能为空");
    var data = Convert.FromBase64String(image);
    //TODO:处理图片
}
以上代码一直工作良好,很久以后接到客户反馈有几张图片一直上传失败,明明选择了图片却还是提示“图片不能为空”。这说明 image 参数没有被正确绑定上。图片的大小为 6MB 左右,这很显然没有突破 IIS 的限制(默认为 30MB),也没有突破 ASP.NET Core 对单个请求大小的限制(默认为 30MB)。我特意去查看了 Windows 日志,也没有看到报错信息。

模拟用户的请求,确实在 HTTP 抓包中看到了图片,但是调试器中 image 确实为空。几番搜索下来,我找到了一个名为 FormOptions 的配置类:
https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.http.features.formoptions?view=aspnetcore-6.0

其中的 ValueLengthLimit 属性有如下定义:
A limit on the length of individual form values. Forms containing values that exceed this limit will throw an InvalidDataException when parsed. Defaults to 4,194,304 bytes‬, which is approximately 4MB.

也就是说:默认情况下,ASP.NET Core 限制了每个 POST 数据值的长度为 4 MB 大小,超过就会抛出 InvalidDataException 异常。我很可能是遇到了这个限制,但因为并没有抛异常所以不太敢确定。
services.Configure<FormOptions>(options=>{
options.ValueLengthLimit = 209715200;//200MB
});
以上代码将限制提升到了 200MB,经测试问题解决。

使用 Base64 将文件编码后虽然会简化,但同时会导致网络传输内容增大,或者遇到本文所示的异常(默认情况下,multipart/form-data 对单个上传项的限制是 128MB)。如果你使用的是 MVC,也可以直接使用 RequestFormLimitsAttribute 解决该问题:
https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.mvc.requestformlimitsattribute?view=aspnetcore-6.0
用户评论