Angular中Uint8Array无法传递到C#,后端FileData为Null
问题:前端传递文件数据到后端,FileData始终为Null
现有代码
C#后端模型
public class TimeSheetManagerModel { public string EmailId { get; set; } = string.Empty; public string EmployeeName { get; set; } = string.Empty; public int Month { get; set; } public int Year { get; set; } public byte[] FileData { get; set; } }
TypeScript前端模型
export class managerModel { employeeName: string; emailId: string; month: number; year: number; fileData: Uint8Array; constructor() { this.employeeName = ""; this.emailId = ""; this.month = 0; this.year = 0; this.fileData = new Uint8Array() } }
前端请求代码
const payload = new managerModel(); this.handleExport().then((arrayBuffer) => { if (arrayBuffer) payload.fileData = new Uint8Array(arrayBuffer); payload.employeeName = this.updateModel.employeeName; payload.emailId = this.updateModel.employeeEmailId; payload.month = this.selectedDate.getMonth(); payload.year = this.selectedDate.getFullYear(); console.log('Payload before sending:', JSON.stringify(payload)); this.timeSheetService.nofityManager(payload) })
Angular服务代码
nofityManager(managerModel: managerModel): Observable<any> { return this.configService.getBaseUrl().pipe( switchMap((baseUrl: string) => { const url = `${baseUrl}/NotifyManager`; const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); return this.http.post<any>(url, managerModel, { headers }); }) ); }
后端接口定义
public async Task<bool> NotifyManager(TimeSheetManagerModel timeSheetManagerModel) { }
问题原因
JSON序列化不支持直接转换Uint8Array,当用JSON.stringify处理包含Uint8Array的对象时,它会被序列化成一个键为索引、值为对应字节的普通对象,后端JSON解析器无法将这种结构映射到byte[]类型,因此FileData始终为Null。
解决方案
方案1:将文件数据转为Base64字符串传输
前端修改
- 更新TypeScript模型,把
fileData类型改为string:
export class managerModel { employeeName: string; emailId: string; month: number; year: number; fileData: string; // 改为string类型存储Base64 constructor() { this.employeeName = ""; this.emailId = ""; this.month = 0; this.year = 0; this.fileData = ""; } }
- 把
Uint8Array转为Base64字符串:
const payload = new managerModel(); this.handleExport().then((arrayBuffer) => { if (arrayBuffer) { // 将Uint8Array转为Base64 const uint8Arr = new Uint8Array(arrayBuffer); const binaryString = Array.from(uint8Arr).map(byte => String.fromCharCode(byte)).join(''); payload.fileData = btoa(binaryString); } // 其他字段赋值不变 payload.employeeName = this.updateModel.employeeName; payload.emailId = this.updateModel.employeeEmailId; payload.month = this.selectedDate.getMonth(); payload.year = this.selectedDate.getFullYear(); console.log('Payload before sending:', JSON.stringify(payload)); this.timeSheetService.nofityManager(payload) })
后端修改
在接口中把Base64字符串转为byte[]:
public async Task<bool> NotifyManager(TimeSheetManagerModel timeSheetManagerModel) { if (!string.IsNullOrEmpty(timeSheetManagerModel.FileData)) { byte[] fileBytes = Convert.FromBase64String(timeSheetManagerModel.FileData); // 使用fileBytes处理业务逻辑 } // 其他逻辑 }
也可以直接修改模型的FileData为string类型,在需要使用时再转换。
方案2:使用FormData传输二进制数据
如果文件较大,Base64会增加约33%的体积,可改用FormData:
前端修改
this.handleExport().then((arrayBuffer) => { const formData = new FormData(); formData.append('employeeName', this.updateModel.employeeName); formData.append('emailId', this.updateModel.employeeEmailId); formData.append('month', this.selectedDate.getMonth().toString()); formData.append('year', this.selectedDate.getFullYear().toString()); if (arrayBuffer) { // 创建Blob对象并添加到FormData const blob = new Blob([arrayBuffer]); formData.append('fileData', blob); } this.timeSheetService.nofityManager(formData) })
Angular服务修改
无需手动设置Content-Type,浏览器会自动处理:
nofityManager(formData: FormData): Observable<any> { return this.configService.getBaseUrl().pipe( switchMap((baseUrl: string) => { const url = `${baseUrl}/NotifyManager`; return this.http.post<any>(url, formData); }) ); }
后端修改
接口添加[FromForm]特性,并将模型的FileData改为IFormFile类型:
public class TimeSheetManagerModel { public string EmailId { get; set; } = string.Empty; public string EmployeeName { get; set; } = string.Empty; public int Month { get; set; } public int Year { get; set; } public IFormFile FileData { get; set; } // 改为IFormFile }
public async Task<bool> NotifyManager([FromForm] TimeSheetManagerModel timeSheetManagerModel) { // 读取文件字节 using var memoryStream = new MemoryStream(); await timeSheetManagerModel.FileData.CopyToAsync(memoryStream); byte[] fileBytes = memoryStream.ToArray(); // 业务逻辑处理 }
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

