如何在ASP.NET WebForm中用WebClient调用ASP.NET Core WebAPI的IFormFile上传接口?
ASP.NET WebForm 调用 ASP.NET Core 3.1 文件上传API 问题解决
问题描述
在ASP.NET Core 3.1中开发了文件上传API,使用Postman或.NET Core项目的HttpClient调用正常,但在ASP.NET WebForm中使用WebClient调用该接口失败,需实现WebForm端正常调用并获取包含上传文件路径和名称的响应。
API核心代码如下:
[HttpPost("Upload")] public IActionResult Upload([FromForm] IFormFile fileUpload) { ResponseViewModel responseModel = new ResponseViewModel(); try { if (fileUpload == null) { responseModel.Message = "Please select file."; return BadRequest(responseModel); } //file upload to temp folder string tempFilPathWithName = Path.GetTempFileName(); using (FileStream file = System.IO.File.OpenWrite(tempFilPathWithName)) { fileUpload.CopyTo(file); } UploadFile uploadFile = new UploadFile() { FileName = fileUpload.FileName, TempFilPathWithName = tempFilPathWithName }; responseModel.Model = uploadFile; responseModel.Message = "File successfully uploaded"; return Ok(responseModel); } catch (Exception ex) { responseModel.ExceptionMessage = ex.ToString(); responseModel.Message = "File upload failed."; } return BadRequest(responseModel); } public class ResponseViewModel { public object Model { get; set; } public string ExceptionMessage { get; set; } public string Message { get; set; } } public class UploadFile { public string FileName { get; set; } public string TempFilPathWithName { get; set; } }
解决方案:WebForm 端正确的 WebClient 调用代码
WebClient调用失败通常是因为未正确构造multipart/form-data格式的请求内容,以下是可正常工作的调用代码:
using System; using System.IO; using System.Net; using System.Text; using System.Web.Script.Serialization; protected void UploadBtn_Click(object sender, EventArgs e) { if (FileUpload1.HasFile) { string apiUrl = "http://your-api-domain/api/Upload"; string fileName = Path.GetFileName(FileUpload1.PostedFile.FileName); using (WebClient client = new WebClient()) { // 构造multipart/form-data边界 string boundary = "----WebKitFormBoundary" + DateTime.Now.Ticks.ToString("x"); client.Headers.Add("Content-Type", $"multipart/form-data; boundary={boundary}"); using (MemoryStream ms = new MemoryStream()) { // 写入文件内容部分 byte[] boundaryBytes = Encoding.ASCII.GetBytes($"\r\n--{boundary}\r\n"); byte[] headerBytes = Encoding.ASCII.GetBytes($"Content-Disposition: form-data; name=\"fileUpload\"; filename=\"{fileName}\"\r\nContent-Type: application/octet-stream\r\n\r\n"); ms.Write(boundaryBytes, 0, boundaryBytes.Length); ms.Write(headerBytes, 0, headerBytes.Length); // 写入文件流 FileUpload1.PostedFile.InputStream.CopyTo(ms); // 写入结束边界 byte[] endBoundaryBytes = Encoding.ASCII.GetBytes($"\r\n--{boundary}--\r\n"); ms.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); ms.Position = 0; // 发送请求并获取响应 byte[] responseBytes = client.UploadData(apiUrl, "POST", ms.ToArray()); string responseString = Encoding.UTF8.GetString(responseBytes); // 解析响应为ResponseViewModel对象 JavaScriptSerializer serializer = new JavaScriptSerializer(); ResponseViewModel responseModel = serializer.Deserialize<ResponseViewModel>(responseString); // 处理响应结果 if (responseModel.Message == "File successfully uploaded") { UploadFile uploadFile = serializer.ConvertToType<UploadFile>(responseModel.Model); Label1.Text = $"上传成功!文件名:{uploadFile.FileName},临时路径:{uploadFile.TempFilPathWithName}"; } else { Label1.Text = $"上传失败:{responseModel.Message},错误信息:{responseModel.ExceptionMessage}"; } } } } else { Label1.Text = "请选择要上传的文件"; } } // WebForm项目中需定义对应的模型类 public class ResponseViewModel { public object Model { get; set; } public string ExceptionMessage { get; set; } public string Message { get; set; } } public class UploadFile { public string FileName { get; set; } public string TempFilPathWithName { get; set; } }
关键注意事项
- 正确构造multipart/form-data请求:WebClient默认不会自动处理文件上传的表单格式,必须手动构造边界、请求头和文件内容,确保匹配API的
[FromForm]接收要求。 - 响应解析:API返回JSON格式数据,需用
JavaScriptSerializer(或Newtonsoft.Json)将响应字符串反序列化为对应模型类,才能提取文件路径和名称。 - 跨域与权限:若API和WebForm部署在不同域名下,需确保API已配置CORS允许WebForm所在域名的请求,否则会触发跨域错误。
内容的提问来源于stack exchange,提问作者Prashant Girase
相关产品推荐
相关产品推荐

