如何从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
相关产品推荐
相关产品推荐

