Angular向ASP.NET Core API传递含IFormFile模型报错求助
问题解决:含IFormFile的模型提交时反序列化失败
问题描述
提交包含8个常规属性与IFormFile类型CorePhoto属性的模型时,无文件请求可正常执行,添加文件后触发内部服务器错误,错误信息:
Error: Deserialization of interface types is not supported. Type 'Microsoft.AspNetCore.Http.IFormFile'. Path: $.corePhoto | LineNumber: 0 | BytePositionInLine: 173.
问题原因
前端以JSON格式传递数据,后端尝试将JSON中的文件字段反序列化为IFormFile接口——而接口无法被JSON反序列化,必须通过multipart/form-data格式的FormData传递文件及表单数据。
解决方案
1. Angular端修改
组件代码调整
将表单所有字段与文件一起存入FormData,而非直接传递JSON:
userFormSubmition(files: any){ const formData = new FormData(); // 遍历表单常规字段,添加到FormData Object.keys(this.userForm.value).forEach(key => { formData.append(key, this.userForm.value[key]); }); // 添加文件,键名需与后端模型的CorePhoto属性完全匹配 if(files.length > 0){ let fileToUpload = <File>files[0]; formData.append('CorePhoto', fileToUpload, fileToUpload.name); } // 传递FormData给服务 this.userService.createUser(formData).subscribe(response => { // 此处添加响应处理逻辑 }); }
服务代码调整
无需手动设置Content-Type,Angular会自动处理multipart/form-data的请求头:
createUser(userCreation: FormData){ return this.http.post(this.url + 'CreateUser', userCreation); }
2. ASP.NET Core端确认与优化
模型与控制器验证
确保模型中IFormFile属性名CorePhoto与前端FormData的键名一致;控制器方法无需添加[FromBody]特性(multipart/form-data通过表单绑定,而非请求体)。
文件上传逻辑优化
添加目录存在性检查,避免因目录不存在导致的错误:
[HttpPost] [Route("CreateUser")] public async Task<IActionResult> CreateUser(ApplicationUserCreationDto userCreationDto) { if (ModelState.IsValid) { var file = userCreationDto.CorePhoto; var folderName = Path.Combine("Resources", "Users/Images"); var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName); // 检查目录是否存在,不存在则创建 if (!Directory.Exists(pathToSave)) { Directory.CreateDirectory(pathToSave); } if (file != null && file.Length > 0) { var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"'); var fullPath = Path.Combine(pathToSave, fileName); var dbPath = Path.Combine(folderName, fileName); using (var stream = new FileStream(fullPath, FileMode.Create)) { await file.CopyToAsync(stream); } } // 后续业务逻辑... return Ok(); } return BadRequest(ModelState); }
内容的提问来源于stack exchange,提问作者mohamed abdou
相关产品推荐
相关产品推荐

