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

ASP.NET Core MVC中如何将GET模型参数传递至POST方法?

解决方案

针对ASP.NET Core MVC中POST方法无法获取GET视图模型原有属性的问题,有以下几种实用方案:

方案1:通过隐藏输入字段传递模型属性

表单提交时只会发送表单内的控件数据,因此可以把需要保留的UserViewModel属性以隐藏字段的形式嵌入表单中,这样POST方法就能完整接收模型数据。

在表单内部添加以下隐藏字段(放在展示代码之后、密码输入框之前即可):

<form asp-controller="Profiles" asp-action="Index" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="mt-4 pt-2 needs-validation" role="form" novalidate>
    <h5>@Model.Username</h5>
    <p>@Model.Roles<br/>@Model.Email</p>
    
    <!-- 添加隐藏字段传递原有模型属性 -->
    <input asp-for="Username" type="hidden" />
    <input asp-for="NameAbbrv" type="hidden" />
    <input asp-for="Roles" type="hidden" />
    <input asp-for="Email" type="hidden" />

    <input asp-for="ChangePassword.OldPassword" class="form-control" id="currentPassword" required autofocus />
    <input asp-for="ChangePassword.NewPassword" id="newPassword" class="form-control" required />
</form>

注意:如果属性包含敏感信息,不建议使用此方案(前端可篡改隐藏字段值)。

方案2:封装公共方法避免代码冗余

将GET方法中获取用户信息的逻辑抽成私有方法,让GET和POST方法共享调用,既避免冗余,又能保证数据是最新的(从数据库重新获取,不受前端篡改影响)。

步骤1:封装获取用户视图模型的私有方法

在控制器中添加以下方法:

private async Task<UserViewModel> GetCurrentUserViewModel()
{
    var userEmail = User.FindFirstValue(ClaimTypes.Name);
    var currentUser = await _userManager.FindByEmailAsync(userEmail);
    var roles = await _userManager.GetRolesAsync(currentUser);

    return new UserViewModel
    {
        Username = $"{currentUser.FirstName} {currentUser.LastName}",
        NameAbbrv = $"{currentUser.FirstName[..1]}{currentUser.LastName[..1]}",
        Roles = string.Join(", ", roles),
        Email = currentUser.Email
    };
}

步骤2:改造GET和POST方法

// GET方法
[HttpGet]
public async Task<IActionResult> Index()
{
    var userViewModel = await GetCurrentUserViewModel();
    return View(userViewModel);
}

// POST方法
[HttpPost]
public async Task<IActionResult> Index(UserViewModel model)
{
    if (!ModelState.IsValid)
    {
        // 验证失败时,重新填充用户基本信息,保留提交的密码表单数据
        var userViewModel = await GetCurrentUserViewModel();
        userViewModel.ChangePassword = model.ChangePassword;
        return View(userViewModel);
    }

    // 执行修改密码的业务逻辑(示例)
    var currentUser = await _userManager.FindByEmailAsync(model.Email);
    var result = await _userManager.ChangePasswordAsync(currentUser, model.ChangePassword.OldPassword, model.ChangePassword.NewPassword);
    
    if (result.Succeeded)
    {
        // 密码修改成功,返回更新后的用户视图模型
        return View(await GetCurrentUserViewModel());
    }

    // 密码修改失败,添加错误信息并返回原视图
    foreach (var error in result.Errors)
    {
        ModelState.AddModelError(string.Empty, error.Description);
    }
    var errorUserViewModel = await GetCurrentUserViewModel();
    errorUserViewModel.ChangePassword = model.ChangePassword;
    return View(errorUserViewModel);
}

方案3:使用TempData临时存储模型(适合重定向场景)

如果POST后需要重定向到其他页面,可以用TempData临时存储视图模型,但需注意TempData是一次性的,且需要序列化对象:

GET方法中存储模型

[HttpGet]
public async Task<IActionResult> Index()
{
    var userViewModel = await GetCurrentUserViewModel();
    TempData["UserViewModel"] = JsonSerializer.Serialize(userViewModel);
    return View(userViewModel);
}

POST方法中读取模型

[HttpPost]
public async Task<IActionResult> Index(UserViewModel model)
{
    if (!ModelState.IsValid)
    {
        var json = TempData["UserViewModel"] as string;
        var userViewModel = JsonSerializer.Deserialize<UserViewModel>(json);
        userViewModel.ChangePassword = model.ChangePassword;
        TempData.Keep("UserViewModel"); // 保留数据以便再次使用
        return View(userViewModel);
    }

    // 处理密码修改逻辑...

    return RedirectToAction(nameof(Index));
}

内容的提问来源于stack exchange,提问作者Jesus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 04:10:29