如何在ASP.NET Core Web API中上传图片并携带其他表单数据?
解决方案:支持表单数据+头像上传的Web API配置及MVC调用实现
一、修正基础代码问题
首先你的User类里有个笔误,Email属性的getl要改为get:
public partial class User { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public string Email { get; set; } // 修正笔误 public string ProfilePhoto { get; set; } // 存储头像的相对路径/文件名 }
二、改造Web API的HttpPost方法
原方法只接收User对象,无法处理文件上传。需要调整为支持表单数据+文件的接收逻辑,步骤如下:
1. 配置静态文件访问(可选)
如果将头像存储在服务器本地,需要在Program.cs中配置静态文件访问,让前端能直接访问上传的图片:
var builder = WebApplication.CreateBuilder(args); // 添加服务... var app = builder.Build(); // 启用默认静态文件访问(对应wwwroot目录) app.UseStaticFiles(); // 如果想将头像存在wwwroot外的自定义目录,可额外配置: // app.UseStaticFiles(new StaticFileOptions // { // FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "ProfilePhotos")), // RequestPath = "/ProfilePhotos" // 前端访问路径前缀 // }); // 其他中间件配置... app.Run();
2. 改造PostUser方法
使用[FromForm]绑定表单数据,同时接收IFormFile类型的头像文件,处理文件保存并更新User的ProfilePhoto字段:
[HttpPost] public async Task<ActionResult<User>> PostUser([FromForm] User user, IFormFile profilePhoto) { if (profilePhoto != null && profilePhoto.Length > 0) { // 生成唯一文件名,避免重复覆盖 var fileName = Guid.NewGuid().ToString() + Path.GetExtension(profilePhoto.FileName); // 定义文件存储路径(这里以wwwroot/ProfilePhotos为例) var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/ProfilePhotos", fileName); // 确保存储目录存在 Directory.CreateDirectory(Path.GetDirectoryName(filePath)); // 将文件写入服务器 using (var stream = new FileStream(filePath, FileMode.Create)) { await profilePhoto.CopyToAsync(stream); } // 给User的ProfilePhoto赋值为前端可访问的相对路径 user.ProfilePhoto = $"/ProfilePhotos/{fileName}"; } _context.User.Add(user); await _context.SaveChangesAsync(); return CreatedAtAction("GetUser", new { id = user.Id }, user); }
3. 可选:配置文件大小限制
如果需要限制上传文件的大小,在Program.cs中添加:
builder.Services.Configure<FormOptions>(options => { options.MultipartBodyLengthLimit = 10 * 1024 * 1024; // 设置为10MB });
三、MVC端调用API实现
1. 创建MVC视图模型
public class UserViewModel { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public string Email { get; set; } public IFormFile ProfilePhoto { get; set; } // 接收前端上传的文件 }
2. MVC控制器调用API的方法
public async Task<IActionResult> CreateUser(UserViewModel model) { if (!ModelState.IsValid) { return View(model); } using (var client = new HttpClient()) { using (var content = new MultipartFormDataContent()) { // 添加表单字段 content.Add(new StringContent(model.FirstName), "FirstName"); content.Add(new StringContent(model.LastName), "LastName"); content.Add(new StringContent(model.Age.ToString()), "Age"); content.Add(new StringContent(model.Email), "Email"); // 添加头像文件 if (model.ProfilePhoto != null) { var fileContent = new StreamContent(model.ProfilePhoto.OpenReadStream()); fileContent.Headers.ContentType = new MediaTypeHeaderValue(model.ProfilePhoto.ContentType); content.Add(fileContent, "profilePhoto", model.ProfilePhoto.FileName); } // 调用Web API var response = await client.PostAsync("https://your-api-domain/api/Users", content); if (response.IsSuccessStatusCode) { return RedirectToAction("Index"); } else { ModelState.AddModelError(string.Empty, "提交失败,请重试"); return View(model); } } } }
3. MVC前端表单视图
注意表单必须设置enctype="multipart/form-data"才能支持文件上传:
@model UserViewModel <form asp-action="CreateUser" enctype="multipart/form-data" class="form-group"> <div> <label asp-for="FirstName"></label> <input asp-for="FirstName" class="form-control" /> <span asp-validation-for="FirstName" class="text-danger"></span> </div> <div> <label asp-for="LastName"></label> <input asp-for="LastName" class="form-control" /> <span asp-validation-for="LastName" class="text-danger"></span> </div> <div> <label asp-for="Age"></label> <input asp-for="Age" class="form-control" /> <span asp-validation-for="Age" class="text-danger"></span> </div> <div> <label asp-for="Email"></label> <input asp-for="Email" class="form-control" /> <span asp-validation-for="Email" class="text-danger"></span> </div> <div> <label asp-for="ProfilePhoto"></label> <input asp-for="ProfilePhoto" type="file" class="form-control" /> <span asp-validation-for="ProfilePhoto" class="text-danger"></span> </div> <button type="submit" class="btn btn-primary mt-3">提交</button> </form>
内容的提问来源于stack exchange,提问作者jo1718
相关产品推荐
相关产品推荐

