问题 ViewBag名称可以与DropDownList中的Model属性名称相同吗?


我正在研究ASP.NET MVC-4 Web应用程序。我在我的action方法中定义了以下内容来构建一个 SelectList

ViewBag.CustomerID = new SelectList(db.CustomerSyncs, "CustomerID", "Name");

然后我渲染我的 DropDownListFor 跟着我的内心 View

 @Html.DropDownListFor(model => model.CustomerID, (SelectList)ViewBag.CustomerID, "please select")

如图所示,我正在命名 ViewBag 财产等于 Model 属性名称是 CustomerID。根据我自己的测试,定义相同的名称不会导致任何问题或冲突,但我应该避免这种情况吗?


10647
2018-05-11 11:25


起源

不要这样做 - 它确实会导致问题(例如,您无法获得任何客户端验证) - Stephen Muecke
@StephenMuecke为什么我不会得到任何客户端验证....现在我将customerID作为int并且它是必需的。并且默认情况下我得到了客户端验证,当用户尝试提交表单时,他将收到需要CustomerID的错误...所以不确定你是什么意思我不能得到任何客户端验证... - john Gu
另一个问题是,如果价值 CustomerID 在控制器中设置(即编辑和现有实体),它将不会在下拉列表中正确选择。 - Stephen Muecke
@StephenMuecke重新回到客户端验证..现在“请选择”的值将为null,因此客户端验证仍然有效..这里是标记<select data-val =“true”data-val -number =“字段CustomerID必须是数字。” data-val-required =“CustomerID字段是必需的。” id =“CustomerID”name =“CustomerID”> <option value =“”>请选择</ option> <option value =“1”> CustomerA </ option> - john Gu
@SeM,绝对不是。您将无法获得客户端验证。 - Stephen Muecke


答案:


您不应该为model属性使用相同的名称 ViewBag 财产(理想情况下你不应该使用 ViewBag 根本就是一个视图模型 IEnumerable<SelectListItem> 属性)。

使用时 @Html.DropDownListFor(m => m.CustomerId, ....) 首先 "Please Select" 即使已设置model属性的值并且与其中一个选项匹配,也始终会选择该选项。原因是该方法首先生成一个新的 IEnumerable<SelectListItem> 基于您提供的那个来设置值 Selected 属性。为了设置 Selected 属性,它读取的值 CustomerID 从 ViewData,它找到的第一个是 "IEnumerable<SelectListItem>" (不是model属性的值)并且不能将该字符串与任何选项匹配,因此选择了第一个选项(因为必须要有)。

使用时 @Html.DropDownList("CustomerId", ....)不,不 data-val-* 将生成属性,您将无法获得任何客户端验证

参考 这个DotNetFiddle 显示可能的用例的比较。只为模型属性和使用不同的名称 ViewBag 财产将全部正常运作。


12
2018-05-11 12:21



好吧,你到处都是 - teo van kot
当我点击提交按钮时,小提琴出错。它说“具有键'CustomerA'的ViewData项是'System.Int32'类型,但必须是'IEnumerable <SelectListItem>'类型。” - Saurabh
@Saurabh,那是因为我没有重新填充 SelectLists 在返回视图之前的POST方法中(根据GET方法) - 但这不是小提琴的重点 - 它表明如果属性使用相同的名称,则无法获得正确的双向绑定和/或验证你绑定和 SelectList (如果您想了解有关该错误的更多详细信息,请参阅 这个问题/答案 - Stephen Muecke


使用它没有害处。你不会得到任何错误。但最佳做法是绑定模型属性。


1
2018-05-11 11:35



@ US3-57384你能更多地考虑吗? - john Gu
看看我在我的代码中使用了什么。这解决了你的问题,工作正常。 (IEnumerable的<SelectListItem>)ViewBag.RT - CrazyDev