Asp.net mvc 奇怪的MVC控制器行为-参数名称与模型冲突
我有一个控制器响应URL,如:Asp.net mvc 奇怪的MVC控制器行为-参数名称与模型冲突,asp.net-mvc,razor,query-string,selectlist,viewbag,Asp.net Mvc,Razor,Query String,Selectlist,Viewbag,我有一个控制器响应URL,如: http://localhost:64121/BrowseNode/Create/1016?nodeTypeId=Category 错误:节点id下拉列表未选择所需元素(id为3)。 动作方式(第3项选择失败): 如果我调试实际代码,nodeTypeId参数的值为“Category”,然后变为3,但我使用的是硬连线值,它仍然失败 然后,如果我使用int参数,而不是enum,则使用以下URL: http://localhost:64121/BrowseNode/Cr
http://localhost:64121/BrowseNode/Create/1016?nodeTypeId=Category
错误:节点id
下拉列表未选择所需元素(id为3)。
动作方式(第3项选择失败):
如果我调试实际代码,nodeTypeId
参数的值为“Category”,然后变为3,但我使用的是硬连线值,它仍然失败
然后,如果我使用int
参数,而不是enum,则使用以下URL:
http://localhost:64121/BrowseNode/Create/1016?nodeTypeId=3
带int参数的操作方法(工程):
view Create.cshtml有两个下拉列表,如:
@LabelFor(model=>model.NodeTypeId,“NodeTypeId”,新的{@class=“controllabel col-md-2”})
@Html.DropDownList(“NodeTypeId”)
@Html.ValidationMessageFor(model=>model.NodeTypeId)
@LabelFor(model=>model.OwnerUserId,“OwnerUserId”,新的{@class=“controllabel col-md-2”})
@Html.DropDownList(“OwnerUserId”)
@Html.ValidationMessageFor(model=>model.OwnerUserId)
问题是:
为什么代码与int
参数一起工作,而与enum
一起失败,即使列表的实际选择值硬连接到3?
更新:
这个问题完全是由于使用namenodeTypeId
作为枚举的参数名造成的。如果我将其重命名为nodetype
,并将url更改为http://localhost:64121/BrowseNode/Create/1016?nodeType=Category
它可以工作
看起来参数名以某种方式被传递到视图中并覆盖了默认值。我不知道参数会从控制器自动传递到MVC视图。有人能解释为什么吗?好的,所以它没有被广泛宣传(或者我在多年的MVC编程中错过了它),但是
查询字符串
参数至少由视图中的某些控件自动使用,优先于同名的ViewBag值
因此,基本上发生的是我的querystringnodeTypeId
字符串参数优先于我的ViewBag
ViewModel
同名属性
DropDownList
显然可以从ViewModel
、SelectList
的选定属性(在匹配的ViewBag属性中)或querystring
参数中获取其当前值
关键是querystring具有优先级,可以用来覆盖默认值(可能非常有用)
你每天都能学到新东西:)
public ActionResult Create([Bind(Prefix = "id")]int? parentBrowseNodeId, Enums.eNodeType? nodeTypeId)
{
int typeId = (int)nodeTypeId.GetValueOrDefault(Enums.eNodeType.Category);
// 3 is hard-wired to test this bug - still does not work
ViewBag.NodeTypeId = new SelectList(db.NodeType, "NodeTypeId", "LabelEN", 3);
ViewBag.OwnerUserId = new SelectList(db.User, "UserId", "EmailAddress", 3);
return View(new CreateItemVM()
{
OwnerUserId = 3,
NodeTypeId = (int)nodeTypeId
});
}
// GET: /BrowseNode/Create
public ActionResult Create([Bind(Prefix = "id")]int? parentBrowseNodeId, int nodeTypeId)
{
ViewBag.NodeTypeId = new SelectList(db.NodeType, "NodeTypeId", "LabelEN", 3);
ViewBag.OwnerUserId = new SelectList(db.User, "UserId", "EmailAddress", 3);
return View(new CreateItemVM()
{
OwnerUserId = 3,
NodeTypeId = 3
});
}
<div class="form-group">
@Html.LabelFor(model => model.NodeTypeId, "NodeTypeId", new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("NodeTypeId")
@Html.ValidationMessageFor(model => model.NodeTypeId)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.OwnerUserId, "OwnerUserId", new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("OwnerUserId")
@Html.ValidationMessageFor(model => model.OwnerUserId)
</div>
</div>