通过Angular向ASP.NET REST API上传图片时Content-Type错误的解决方法
解决Angular向ASP.NET REST API上传图片时的Content-Type错误
错误提示System.InvalidOperationException: Incorrect Content-Type:application/json的核心原因是:
- 后端控制器通过
Request.Form.Files读取上传文件,这种方式要求请求的Content-Type必须是multipart/form-data - 你当前前端是将图片转成base64字符串后封装到JSON对象里发送,请求的Content-Type是默认的
application/json,后端读取Form.Files时自然会报错。
以下是两个可行的解决方案,选择其一即可:
方案一:改用FormData发送文件(推荐,符合文件上传标准)
这种方式直接上传文件二进制数据,比base64更高效,也符合REST API文件上传的常规做法。
1. 修改Angular组件代码
去掉base64转换逻辑,直接用FormData存储表单数据和文件:
export class PostAdvComponent implements OnInit { advForm: FormGroup; selectedFiles: File[] = []; constructor(private fb: FormBuilder, private advService: AdvService) { } ngOnInit(): void { this.advForm = this.fb.group({ id: [0], name: ['', [Validators.required, Validators.minLength(1), Validators.maxLength(50)]], price: ['', Validators.required], description: ['', Validators.required] }); } uploadImage(event: any) { this.selectedFiles = Array.from(event.target.files); } addAdvertisement() { const formData = new FormData(); // 追加表单字段 formData.append('Id', this.advForm.get('id')?.value.toString()); formData.append('Name', this.advForm.get('name')?.value); formData.append('Price', this.advForm.get('price')?.value.toString()); formData.append('Description', this.advForm.get('description')?.value); // 追加文件 this.selectedFiles.forEach(file => { formData.append('Images', file); }); this.advService.postAdv(formData) .subscribe(add => { console.log(add); }); } }
2. 修改Angular服务的post方法
无需手动设置Content-Type,HttpClient会自动为FormData设置正确的multipart/form-data头:
// AdvService中的postAdv方法 postAdv(formData: FormData): Observable<any> { return this.http.post('你的API接口地址', formData); }
3. 修改ASP.NET控制器代码
调整参数绑定逻辑,直接读取FormData中的字段和文件:
public IActionResult PostAdv() { try { var model = new AdvModel { Id = int.Parse(Request.Form["Id"]), Name = Request.Form["Name"], Price = decimal.Parse(Request.Form["Price"]), Description = Request.Form["Description"] }; Advertisement entity = new Advertisement(); entity.Id = model.Id; entity.Name = model.Name; entity.Price = model.Price; entity.Description = model.Description; foreach (var file in Request.Form.Files) { if (file.Length > 0) { using (MemoryStream ms = new MemoryStream()) { file.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); } }
方案二:沿用base64字符串上传(调整后端逻辑)
如果坚持使用base64方式,需要修改后端不再依赖Request.Form.Files,直接解析模型中的base64字符串:
1. 修正前端base64处理的错误
当前前端的base64处理存在正则错误和表单赋值路径错误,修改如下:
uploadImage(event: any) { const files = event.target.files; const imagesArray = this.advForm.get('images') as FormArray; imagesArray.clear(); for (let i = 0; i < files.length; i++) { const file = files[i]; const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { const base64String = reader.result as string; // 去掉base64前缀(如data:image/png;base64,) const pureBase64 = base64String.split(',')[1]; imagesArray.push(this.fb.group({ id: 0, contents: pureBase64 })); } } }
2. 修改ASP.NET控制器代码
不再读取Request.Form.Files,而是从AdvModel.Images中解析base64字符串为byte[]:
public IActionResult PostAdv(AdvModel model) { try { Advertisement entity = new Advertisement(); entity.Id = model.Id; entity.Name = model.Name; entity.Price = model.Price; entity.Description = model.Description; foreach (var imgModel in model.Images) { if (!string.IsNullOrEmpty(imgModel.Contents)) { byte[] imageBytes = Convert.FromBase64String(imgModel.Contents); entity.Images.Add(new Image { Contents = imageBytes }); } } new AdvHandler().PostAdv(entity); return Created(Request.Path, entity.ToModel()); } catch (Exception ex) { return StatusCode(500, ex); } }
内容的提问来源于stack exchange,提问作者Junior Dev
相关产品推荐
相关产品推荐

