Angular14向ASP.NET6上传FormData报错:请求表单读取失败
解决FormData上传流读取错误的方案
1. 修复Angular服务的请求头问题
手动指定multipart/form-data的boundary会和浏览器自动生成的冲突,导致ASP.NET无法正确解析请求体。直接移除自定义的Content-Type头:
修改服务类代码:
postAdvertisement(formData: FormData): Observable<Advertisement> { // 移除手动设置的Content-Type,浏览器会自动处理边界符 return this.http.post<Advertisement>(this.baseApiUrl + '/api/advertisements', formData); }
2. 修正Angular组件中FormData的字段映射
当前FormData的字段名和API端模型不匹配,数组字段格式错误,导致模型绑定失败,同时间接引发流读取冲突。调整FormData构建逻辑:
修改组件的addAdvertisement方法:
addAdvertisement() { this.mapFormValuesToAdvModel(); const formData = new FormData(); formData.append('id', this.adv.id.toString()); formData.append('name', this.adv.name); formData.append('price', this.adv.price.toString()); formData.append('description', this.adv.description); // 正确映射Features数组,使用索引格式匹配API模型 this.adv.features.forEach((feature, index) => { formData.append(`features[${index}].id`, feature.id.toString()); formData.append(`features[${index}].name`, feature.name); }); // 正确映射Images数组的文件字段,对应API模型的Contents属性 this.files.forEach((file, index) => { formData.append(`images[${index}].Contents`, file, file.name); formData.append(`images[${index}].id`, '0'); }); this.advertisementService.postAdvertisement(formData) .subscribe(add => { console.log(add); }); }
3. 修正ASP.NET控制器的请求读取逻辑
控制器中同时使用[FromForm] AdvModel model和Request.Form.Files会导致请求流被两次读取,触发“Unexpected end of Stream”错误。直接从绑定后的模型中获取文件:
修改控制器代码:
[HttpPost] [Consumes("multipart/form-data")] public IActionResult PostAdv([FromForm] AdvModel model) { try { Advertisement entity = new Advertisement(); entity.Id = model.Id; entity.Name = model.Name; entity.Price = model.Price; entity.Description = model.Description; entity.Features = model.Features.ToEntityList(); // 直接从模型的Images集合中取文件,避免重复读取请求流 foreach (var imageModel in model.Images) { if (imageModel.Contents != null && imageModel.Contents.Length > 0) { using (MemoryStream ms = new MemoryStream()) { imageModel.Contents.CopyTo(ms); entity.Images.Add(new Image { Contents = ms.ToArray() }); } } } new AdvHandler().PostAdv(entity); return Created(Request.Path, entity.ToModel()); } catch (Exception ex) { return StatusCode(500, ex.Message); // 返回错误信息而非完整异常对象 } }
4. 确保AdvModel定义正确
确认API端的AdvModel包含对应集合属性,保证模型绑定能正确解析:
public class AdvModel { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Description { get; set; } public List<FeatureModel> Features { get; set; } public List<ImageModel> Images { get; set; } } public class FeatureModel { public int Id { get; set; } public string Name { get; set; } }
关键原因总结
- Angular端手动设置Content-Type导致边界符不匹配,ASP.NET无法解析请求体。
- 控制器重复读取请求流(模型绑定一次,
Request.Form.Files一次),导致流提前耗尽。 - FormData字段名与API模型字段不匹配,模型绑定失败后触发后续流读取错误。
内容的提问来源于stack exchange,提问作者Junior Dev
相关产品推荐
相关产品推荐

