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

ASP.NET Core中未赋值的Model属性为何自动获得值?

ASP.NET Core局部视图中隐藏字段Id自动赋值的原因及解决方法

问题描述

我编写了一个ASP.NET Core控制器Action,返回携带空AccountHistoryFormModel的局部视图,但在浏览器中检查时,发现Id对应的隐藏元素带有值。

相关代码

Controller

[HttpGet]
public async Task<IActionResult> GetItemForm(int? id)
{
    try
    {
        //var account = await _uow.CashAccounts.GetAsync((int)id);

        //if (account == null)
        //    return Json(new NotFound());

        var model = new AccountHistoryFormModel();
        //model.AccountId = (int)id;

        return PartialView("_AddFundForm", model);
    }
    catch (Exception ex)
    {
        return Json(new InternalError(ex.Message));
    }
}

View

@using Trucking.WebUI.Models.BankAccount
@model AccountHistoryFormModel

@using (Html.BeginForm("save", "accounthistory", FormMethod.Post, new { id = "add-fund-form", @class = "row g-2" }))
{
    @Html.HiddenFor(x => x.Id)
    //@Html.HiddenFor(x => x.AccountId)
    <div class="col-md-6">
        @Html.LabelFor(x => x.Amount, new { @class = "form-label form-label-sm" })
        @Html.TextBoxFor(x => x.Amount, new { @class = "form-control form-control-sm" })
        @Html.ValidationMessageFor(x => x.Amount, "", new { @class="invalid-feedback" })
    </div>
    <div class="col-md-6">
        @Html.LabelFor(x => x.DateDeposit, new { @class = "form-label form-label-sm" })
        @Html.TextBoxFor(x => x.DateDeposit, "{0:yyyy-MM-dd}", new { @type = "date", @class = "form-control form-control-sm" })
        @Html.ValidationMessageFor(x => x.DateDeposit, "", new { @class = "invalid-feedback" })
    </div>
}

AccountHistoryFormModel

public class AccountHistoryFormModel : BaseModel
{
    public AccountHistoryFormModel()
    {
        Action = "DEPOSIT";
        DateDeposit = DateTime.Now;
    }

    public int AccountId { get; set; }

    [Range(1.0, double.MaxValue, ErrorMessage = "Amount must not be 0.")]
    public decimal Amount { get; set; }
    public string Action { get; }

    [Display(Name = "Date Deposit")]
    public DateTime DateDeposit { get; set; }
}

原因分析

这是ASP.NET Core模型绑定的**“值重放”机制**导致的:

  • Action接收的int? id参数会被自动存入请求上下文的ModelState集合中。
  • 使用@Html.HiddenFor(x => x.Id)时,HtmlHelper会优先从ModelState中匹配取值(模型绑定不区分大小写,id和Id会被识别为同一键),而非使用新建模型实例的Id默认值(int类型默认值为0)。
  • 因此即便创建了空模型,隐藏字段依然会被填充为请求URL传入的id参数值。

解决方法

方法一:清除ModelState中对应的键

在返回视图前移除ModelState里的Id键,让Helper使用模型实例的值:

var model = new AccountHistoryFormModel();
ModelState.Remove("Id"); // 清除ModelState中的Id值
return PartialView("_AddFundForm", model);

方法二:重命名Action参数避免冲突

将Action参数名从id改为其他名称(比如accountId),避免和模型的Id属性名称匹配:

public async Task<IActionResult> GetItemForm(int? accountId)
{
    // 后续逻辑不变
}

方法三:手动指定隐藏字段值

不使用HiddenFor,改用Html.Hidden手动指定值,强制使用模型实例的Id:

@Html.Hidden("Id", Model.Id)

内容的提问来源于stack exchange,提问作者John Louie Dela Cruz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:54:14