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

如何从Angular向.NET上传文件?解决JSON转byte[]失败问题

问题解决:Angular向.NET上传文件时JSON转byte[]失败的处理方案

你遇到的错误核心原因是:JSON格式无法直接将前端的File对象转换为.NET的byte[]类型。需要改用multipart/form-data格式来同时上传文件和表单数据,以下是具体修改步骤:

后端(.NET)修改

1. 更新DoctorRegisterDto

将byte[]类型的文件字段替换为.NET专门处理上传文件的IFormFile类型:

public class DoctorRegisterDto
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Password { get; set; }
    public string Idnumber { get; set; }
    public string Email { get; set; }
    public int Views { get; set; }
    public string Categories { get; set; }
    public string Description { get; set; }
    public IFormFile Photo { get; set; } // 替换为IFormFile
    public IFormFile Cv { get; set; } // 替换为IFormFile
}

2. 修改注册接口

去掉[FromBody],改用[FromForm]接收表单数据,并在接口内将IFormFile转换为byte[]存入数据库:

[HttpPost("register-doctor")]
public async Task<ActionResult<UserDto>> Register([FromForm] DoctorRegisterDto registerDto)
{
    using var hmac = new HMACSHA512();

    // 转换Photo为byte[]
    byte[] photoBytes = null;
    if (registerDto.Photo != null)
    {
        using var ms = new MemoryStream();
        await registerDto.Photo.CopyToAsync(ms);
        photoBytes = ms.ToArray();
    }

    // 转换Cv为byte[]
    byte[] cvBytes = null;
    if (registerDto.Cv != null)
    {
        using var ms = new MemoryStream();
        await registerDto.Cv.CopyToAsync(ms);
        cvBytes = ms.ToArray();
    }

    var user = new Doctor
    {
        Firstname = registerDto.Firstname.ToLower(),
        Lastname = registerDto.Lastname.ToLower(),
        Idnumber = registerDto.Idnumber,
        Email = registerDto.Email.ToLower(),
        PasswordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(registerDto.Password)),
        PasswordSalt = hmac.Key,
        Categories = registerDto.Categories,
        Views = 0,
        Description = registerDto.Description,
        Photo = photoBytes,
        Cv = cvBytes
    };
    await _context.Doctors.AddAsync(user);
    await _context.SaveChangesAsync();

    return new UserDto { Username = user.Firstname, Token = _tokenService.CreateTokenDoctor(user) };
}

前端(Angular)修改

不再用JSON格式发送请求,改用FormData包装所有字段和文件:

onSubmit() {
  const formData = new FormData();
  
  // 追加普通表单字段
  formData.append('Firstname', this.registerForm.get('firstname').value);
  formData.append('Lastname', this.registerForm.get('lastname').value);
  formData.append('Password', this.registerForm.get('password').value);
  formData.append('Idnumber', this.registerForm.get('idnumber').value);
  formData.append('Email', this.registerForm.get('email').value);
  formData.append('Views', this.registerForm.get('views').value.toString()); // 数字转字符串
  formData.append('Categories', this.registerForm.get('categories').value);
  formData.append('Description', this.registerForm.get('description').value);
  
  // 追加文件
  const photoFile = this.registerForm.get('photo').value;
  if (photoFile) {
    formData.append('Photo', photoFile);
  }
  
  const cvFile = this.registerForm.get('cv').value;
  if (cvFile) {
    formData.append('Cv', cvFile);
  }
  
  // 发送请求
  this.http.post('/api/register-doctor', formData).subscribe(
    response => {
      // 处理成功逻辑
    },
    error => {
      // 处理错误逻辑
    }
  );
}

同时确保HTML中的文件输入框绑定正确:

<input type="file" formControlName="photo" accept="image/*">
<input type="file" formControlName="cv" accept=".pdf,.doc,.docx">

内容的提问来源于stack exchange,提问作者Luka Shekelashvili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 23:04:55