You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fetch时ASP.NET MVC控制器无法绑定ProfileViewModel的问题

问题解决:ASP.NET MVC Fetch传参绑定与标准表单弹窗实现

一、Fetch传参时ProfileViewModel接收为null的问题及解决

核心错误原因

  1. 请求头未正确配置:Fetch默认发送的请求头为text/plain,ASP.NET MVC无法自动识别请求体中的JSON数据,导致模型绑定失败。
  2. 缺少[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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:48:13