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
相关产品推荐
相关产品推荐

