hiddenFor助手正在从操作参数而不是viewModel中提取ID [英] hiddenFor helper is pulling id from action parameter, not the viewModel

查看:132
本文介绍了hiddenFor助手正在从操作参数而不是viewModel中提取ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我偶然发现了ASP.Net MVC的一个非常奇怪的情况,传递了一个"id"作为操作参数和一个"id"隐藏表单元素.我有一个具有"id"参数的动作.此id值代表一个项目.我有一个控制器操作,在该操作中,我正在创建一个数据输入表单,用于将员工分配给传入的项目(我创建了一个下拉列表,管理员在其中选择了要分配给传入项目的员工).通过将雇员分配给项目,我创建了一个ProjectEmployee记录(项目ID,雇员ID和代表组合的ID,该ID是数据库中的标识列).标识列(称为"id")也是一个隐藏的表单元素.这是必要的,因为我需要能够在以后编辑项目/员工分配.

I've stumbled upon a really weird situation with ASP.Net MVC, passing an "id" as an action parameter and an "id" hidden form element. I have an action that has an "id" parameter. This id value represents a project. I have a controller action where I'm creating a data entry form for assigning an employee to the passed in project (I create a drop down list where administrator selects an employee to be assigned to passed project). By assigning an employee to a project, I create a ProjectEmployee record (project id, employee id, and an id that represents the combination which is an identity column in the database). The identity column (which is named "id") is also a hidden form element. This is necessary because I need to be able to edit the project/employee assignment at a later date.

无论如何,在为项目创建新的员工分配时,会将项目ID(即传递给操作的"ID")应用于"ID"隐藏表单元素.

Anyways, when creating a new employee assignment to a project, the project id (which is the "id" being passed to the action) is being applied to the "id" hidden form element.

我正在将117传递给动作. 117是projectId.正在将其设置为"id"隐藏字段,该字段应为0,因为0表示新的项目/员工分配.

I'm passing 117 into the action. 117 is the projectId. It's being set to the "id" hidden field which should be 0 because 0 represents a new project/employee assignemnt.

查看模型

id  - unique id that represents the Project/Employee combination
projectId - the "Id" being passed to action
EmployeeId - what the admin is selecting from drop down
rate
startdate
endDate
...

数据输入表

@Html.HiddenFor(m => m.Id) 
@Html.HiddenFor(m => m.ProjectId)
...
Id: @Model.Id <br />
ProjectId: @Model.ProjectId<br />

因此,@ Html.HiddenFor(m => m.Id)呈现值为117的隐藏表单元素.@ Model.Id向UI呈现0.逐步执行代码,我可以直观地看到Id属性的值为0.HiddenFor是如何使其导线交叉并拉出117的值的?

So, @Html.HiddenFor(m => m.Id) renders a hidden form element with a value of 117. @Model.Id renders 0 to the UI. Stepping through the code I can visually see the value of the Id property to be 0. How come HiddenFor is getting it's wires crossed and pulling the value of 117?

此错误已投入生产,因此我手头一团糟,数据混乱,因为我实际上是在更新现有记录,而不是在数据库表中创建新记录,因为"Id"属性是错误地从0(代表新记录)设置为117(这是projectId),因此正在更新其他记录.

This bug has made it's way into production so I have a mess on my hands with data getting messed up because instead of creating a new record in the database table, I'm actually UPDATING existing records because the "Id" property is erroneously getting set from 0 (which represents a new record) to 117 (which is the projectId) and therefore am updating a different record.

推荐答案

HiddenFor怎么把电线交叉并拉到117的值?

How come HiddenFor is getting it's wires crossed and pulling the value of 117?

这是设计使然.所有HTML帮助器(例如TextBoxFor和HiddenFor)在绑定时都首先使用ModelState的值,然后使用模型的值.我认为您的控制器动作如下所示:

That's by design. All HTML helpers such as TextBoxFor and HiddenFor first use the value of ModelState when binding and then the value of the model. I presume your controller action looks like this:

public ActionResult Foo(int id)
{
    SomeModel model = ...
    // At this stage model.Id = 0
    return View(model);
}

问题是默认的模型绑定器通过键id将一个值添加到ModelState中,该键由助手使用,并且模型属性值将被忽略.这不是错误.这就是HTML帮助器的设计方式.起初您不知道时会有些困惑,但是一旦您习惯了这种行为,就不会再陷入陷阱了.

The thing is that the default model binder adds a value into the ModelState with the key id which is used by the helper and the model property value is ignored. This is not a bug. It is how the HTML helpers are designed. It's a bit confusing in the beginning when you don't know it, but once you get accustomed to this behavior you don't fall in the trap a second time.

解决此问题的一种可能性是从ModelState中删除该值:

One possibility to fix the problem is to remove this value from ModelState:

public ActionResult Foo(int id)
{
    ModelState.Remove("id");
    SomeModel model = ...
    // At this stage model.Id = 0
    return View(model);
}

或将模型中的Id属性重命名为其他名称以避免冲突.

Or rename the Id property inside your model to something else to avoid the conflict.

这篇关于hiddenFor助手正在从操作参数而不是viewModel中提取ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆