Web API控制器处理JSON数据:AngularJS传含文件列表数据的问询
嘿,这个场景我熟!你要处理的是混合了普通JSON数据和文件上传的请求,直接传纯JSON肯定不行——因为文件是二进制内容,得用FormData来封装数据。我给你梳理清楚两端的关键代码,再讲Web API怎么接收:
第一步:修正AngularJS端的请求代码
首先你需要把JSON数据和文件都装进FormData里,这是处理文件上传的标准方式。补全你的控制器代码:
app.controller("demoController", function ($scope, $http) { $scope.files = []; $scope.jsonData = { name: "Sibnz", comments: "This is a comment" }; // 监听文件选中事件,获取选中的文件列表 $scope.onFileSelect = function (files) { $scope.files = Array.from(files); // 把FileList转成数组方便操作 }; // 提交数据到Web API的方法 $scope.submitData = function () { const formData = new FormData(); // 把JSON对象转成字符串,添加到FormData中 formData.append('jsonData', JSON.stringify($scope.jsonData)); // 遍历文件列表,逐个添加到FormData $scope.files.forEach(file => { formData.append('files', file); }); // 发送POST请求 $http({ method: 'POST', url: '/api/uploader/submit', // 替换成你的Web API接口地址 data: formData, headers: { 'Content-Type': undefined }, // 关键:让浏览器自动设置正确的multipart请求头 transformRequest: angular.identity // 禁用Angular默认的请求转换,FormData会自己处理 }).then(response => { console.log('上传成功!', response.data); }, error => { console.error('上传失败', error); }); }; });
第二步:Web API控制器接收数据
根据你使用的ASP.NET版本,分两种情况处理:
情况1:ASP.NET Core Web API
首先定义一个接收JSON数据的模型:
public class JsonDataModel { public string Name { get; set; } public string Comments { get; set; } }
然后编写控制器的Action,用[FromForm]绑定FormData中的内容:
[Route("api/[controller]")] [ApiController] public class UploaderController : ControllerBase { [HttpPost("submit")] public async Task<IActionResult> SubmitData([FromForm] string jsonData, [FromForm] List<IFormFile> files) { // 1. 把JSON字符串反序列化成模型 var dataModel = System.Text.Json.JsonSerializer.Deserialize<JsonDataModel>(jsonData); // 2. 处理上传的文件(示例:保存到服务器指定目录) var savePath = Path.Combine(Directory.GetCurrentDirectory(), "Uploads"); if (!Directory.Exists(savePath)) { Directory.CreateDirectory(savePath); } foreach (var file in files) { if (file.Length > 0) { var filePath = Path.Combine(savePath, file.FileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(stream); } } } return Ok(new { Message = "数据和文件接收成功", ReceivedName = dataModel.Name, ReceivedComment = dataModel.Comments, UploadedFileCount = files.Count }); } }
情况2:ASP.NET Framework Web API(Web API 2)
同样先定义JSON数据模型,然后用MultipartFormDataStreamProvider来解析请求:
public class JsonDataModel { public string Name { get; set; } public string Comments { get; set; } } public class UploaderController : ApiController { [HttpPost] [Route("submit")] public async Task<IHttpActionResult> SubmitData() { // 检查请求格式是否正确 if (!Request.Content.IsMimeMultipartContent()) { return BadRequest("请求必须是multipart/form-data格式"); } // 设置文件临时存储路径 var savePath = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/Uploads")); if (!Directory.Exists(savePath)) { Directory.CreateDirectory(savePath); } var provider = new MultipartFormDataStreamProvider(savePath); try { // 读取所有multipart数据 await Request.Content.ReadAsMultipartAsync(provider); // 获取并反序列化JSON数据 var jsonDataString = provider.FormData.GetValues("jsonData").FirstOrDefault(); var dataModel = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonDataModel>(jsonDataString); // 获取上传的文件列表 var uploadedFiles = provider.FileData.Select(file => new FileInfo(file.LocalFileName)); // 可选:重命名文件为原始文件名(默认会生成随机文件名) foreach (var fileData in provider.FileData) { var originalFileName = fileData.Headers.ContentDisposition.FileName.Trim('"'); var newFilePath = Path.Combine(savePath, originalFileName); File.Move(fileData.LocalFileName, newFilePath); } return Ok(new { Message = "上传成功", ReceivedName = dataModel.Name, UploadedFileCount = uploadedFiles.Count() }); } catch (Exception ex) { return InternalServerError(ex); } } }
关键注意事项
- AngularJS端必须用
FormData封装数据,不能直接传JSON,否则文件无法被Web API解析。 - 请求头的
Content-Type必须设为undefined,让浏览器自动添加包含边界符的multipart/form-data头,否则Web API无法识别请求结构。 - Web API端要确保接口允许
multipart/form-data请求,ASP.NET Core默认支持,ASP.NET Framework需要确保配置正确。
内容的提问来源于stack exchange,提问作者Hoster
相关产品推荐
相关产品推荐

