.NET Core反序列化FormFile对象抛出奇怪异常是什么原因?
问题根因
Microsoft.AspNetCore.Http.FormFile类型本身未设计为支持JSON序列化/反序列化场景:
- 该类型的
ContentDisposition、ContentType等属性的setter内部依赖类型初始化时创建的私有元数据对象 - JSON序列化时只会读取公开属性的值,不会序列化私有字段,反序列化时直接构造空的FormFile对象,未初始化内部依赖的私有字段,给
ContentDisposition赋值时就会触发空引用异常
解决方案
不要直接序列化FormFile对象,自定义可序列化的文件传输DTO存储所需的文件信息,步骤如下:
1. 定义可序列化的文件DTO
public class SerializableFileDto { public string FileName { get; set; } public string ContentType { get; set; } public string ContentDisposition { get; set; } public long Length { get; set; } // 存储文件二进制内容 public byte[] FileContent { get; set; } }
2. 序列化前转换为DTO
// 把FormFile转成DTO using var memoryStream = new MemoryStream(); await file.CopyToAsync(memoryStream); var fileDto = new SerializableFileDto { FileName = file.FileName, ContentType = file.ContentType, ContentDisposition = file.ContentDisposition, Length = file.Length, FileContent = memoryStream.ToArray() }; // 序列化DTO存入TempData var serializedFile = JsonConvert.SerializeObject(fileDto, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, NullValueHandling = NullValueHandling.Ignore, }); TempData["myFile"] = serializedFile;
3. 反序列化后按需转为FormFile
// 先反序列化为DTO var fileDto = JsonConvert.DeserializeObject<SerializableFileDto>(TempData["myFile"].ToString(), new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, NullValueHandling = NullValueHandling.Ignore, }); // 如果需要使用FormFile对象,手动构造 var deserializedFile = new FormFile( baseStream: new MemoryStream(fileDto.FileContent), baseStreamOffset: 0, length: fileDto.Length, name: "file", fileName: fileDto.FileName) { ContentType = fileDto.ContentType, ContentDisposition = fileDto.ContentDisposition };
注意事项
- TempData默认存储上限为4MB,如果文件大小超出该限制,建议改为存到服务器临时目录,TempData只存储临时文件路径
- 文件处理完成后及时清理临时文件,避免占用服务器存储
内容的提问来源于stack exchange,提问作者Rocker2982
相关产品推荐
相关产品推荐

