You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:54:57