使用Fetch时ASP.NET MVC控制器无法绑定ProfileViewModel的问题
问题解决:ASP.NET MVC Fetch传参绑定与标准表单弹窗实现
一、Fetch传参时ProfileViewModel接收为null的问题及解决
核心错误原因
- 请求头未正确配置:Fetch默认发送的请求头为
text/plain,ASP.NET MVC无法自动识别请求体中的JSON数据,导致模型绑定失败。 - 缺少[FromBody]特性:未明确告知控制器从请求体中读取参数进行绑定。
正确实现方案
前端Fetch代码
const profileData = { Name: "张三", Email: "zhangsan@example.com" }; fetch('/Profile/Update', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': document.querySelector('input[name="__RequestVerificationToken"]').value }, body: JSON.stringify(profileData) }) .then(response => response.json()) .then(data => { data.success ? Swal.fire('成功', '资料更新完成', 'success') : Swal.fire('失败', data.message, 'error'); }) .catch(() => Swal.fire('错误', '请求发生异常', 'error'));
后端控制器代码
using Microsoft.AspNetCore.Mvc; public class ProfileController : Controller { [HttpPost] public IActionResult Update([FromBody] ProfileViewModel model) { if (ModelState.IsValid) { // 执行业务逻辑 return Json(new { success = true, message = "更新成功" }); } var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage); return Json(new { success = false, message = string.Join(";", errors) }); } } public class ProfileViewModel { public string Name { get; set; } public string Email { get; set; } }
临时方案:将object转换为ProfileViewModel(不推荐)
如果暂时无法修正绑定问题,可通过序列化转换,但这属于绕开根源问题的临时手段:
using System.Text.Json; [HttpPost] public IActionResult Update(object rawData) { var jsonString = JsonSerializer.Serialize(rawData); var model = JsonSerializer.Deserialize<ProfileViewModel>(jsonString); // 后续业务处理 }
二、使用ASP.NET标准表单实现Swal.fire弹窗效果
可以保留标准表单结构,通过阻止默认提交+AJAX请求实现弹窗交互:
表单代码
<form id="profileForm" asp-controller="Profile" asp-action="Update" method="post"> @Html.AntiForgeryToken() <div> <label>姓名:</label> <input asp-for="Name" type="text" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <div> <label>邮箱:</label> <input asp-for="Email" type="email" /> <span asp-validation-for="Email" class="text-danger"></span> </div> <button type="submit">提交</button> </form>
前端交互代码
document.getElementById('profileForm').addEventListener('submit', function(e) { e.preventDefault(); // 阻止默认表单跳转 const formData = new FormData(this); fetch(this.action, { method: this.method, body: formData }) .then(response => response.json()) .then(data => { data.success ? Swal.fire('成功', '资料更新完成', 'success') : Swal.fire('失败', data.message, 'error'); }) .catch(() => Swal.fire('错误', '请求发生异常', 'error')); });
后端控制器代码
无需添加[FromBody],表单数据会自动绑定到ViewModel:
[HttpPost] public IActionResult Update(ProfileViewModel model) { if (ModelState.IsValid) { // 执行业务逻辑 return Json(new { success = true, message = "更新成功" }); } var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage); return Json(new { success = false, message = string.Join(";", errors) }); }
内容的提问来源于stack exchange,提问作者Maximka
相关产品推荐
相关产品推荐

