.NET Web API接收Angular multipart-formdata参数为null问题
Angular表单提交至.NET Core Web API时,SampleDTO字段全为null的解决方法
问题描述
使用Angular表单提交请求至.NET Core Web API时,SampleDTO的Name字段和File字段均接收为null,相关代码如下:
.NET Core API代码
[HttpPost("file")] public ActionResult<string> Upload([FromForm]SampleDTO dto) { try { var folderName = Path.Combine("wwwroot", "Images/products"); var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName); if (dto.File != null && dto.File?.Length > 0) { var fileName = ContentDispositionHeaderValue.Parse(dto.File.ContentDisposition) .FileName.Trim('"'); var fullPath = Path.Combine(pathToSave, fileName); var dbPath = Path.Combine(folderName, fileName); using (var stream = new FileStream(fullPath, FileMode.Create)) { dto.File.CopyTo(stream); return Ok(dto.File.FileName+" "); } } return BadRequest(); } catch (System.Exception) { return BadRequest(); } }
DTO代码
public class SampleDTO { [Required] public string Name { get; set; } [Required] public IFormFile File { get; set; } }
Angular接口定义
export interface ISample { name:string; file:File; }
Angular服务方法
createSample(data:any) { return this.http.post("https://localhost:7169/api/product/file",data); }
Angular组件提交方法
onSubmit(data:any) { console.log(data as ISample); this.productService.createSample(data as ISample).subscribe(res=>console.log(res)); }
Angular组件文件赋值方法
onChange(event:any) { this.file = event.target.files[0] as File; this.testForm.patchValue( { file:this.file }); }
Angular HTML代码
<form [formGroup]="this.testForm"> <input type="text" name="name" id="name" formControlName="name"> <input type="file" name="file" id="file" (change)="onChange($event)"> <button (click)="this.onSubmit(this.testForm.value)">Submit</button> </form>
解决方法
1. 改用FormData构建请求数据
上传文件必须使用multipart/form-data格式,不能直接传递JSON对象。修改Angular组件的提交方法:
onSubmit(data: any) { const formData = new FormData(); // 键名必须与.NET DTO的属性名完全匹配(区分大小写) formData.append('Name', data.name); formData.append('File', data.file); this.productService.createSample(formData).subscribe(res => console.log(res)); }
2. 确保服务请求头正确
Angular的HttpClient在发送FormData时会自动设置Content-Type: multipart/form-data,无需手动添加。如果之前手动设置过JSON相关请求头,需要移除:
createSample(data: FormData) { return this.http.post("https://localhost:7169/api/product/file", data); }
3. 严格匹配属性大小写
.NET模型绑定区分大小写,FormData的键名必须和DTO的属性名一致(如Name而非name),否则无法完成绑定。
4. 优化文件控件的处理(可选)
可以直接从DOM获取文件对象,避免表单patchValue的潜在问题:
onSubmit() { const name = this.testForm.get('name')?.value; const fileInput = document.getElementById('file') as HTMLInputElement; const file = fileInput.files?.[0]; if (file) { const formData = new FormData(); formData.append('Name', name); formData.append('File', file); this.productService.createSample(formData).subscribe(res => console.log(res)); } }
原因说明
.NET API使用[FromForm]标记,要求请求数据为multipart/form-data格式,但原Angular代码直接传递JSON对象,导致API无法解析请求内容,最终DTO字段全部为null。改用FormData后,请求格式与API要求匹配,模型绑定即可正常完成。
内容的提问来源于stack exchange,提问作者silent9
相关产品推荐
相关产品推荐

