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

Posted

技术标签:

【中文标题】ViewBag 名称可以与 DropDownList 中的 Model 属性名称相同吗?【英文标题】:Can the ViewBag name be the same as the Model property name in a DropDownList? 【发布时间】:2016-09-06 18:28:58 【问题描述】:

我正在开发一个 ASP.NET MVC-4 Web 应用程序。我在我的操作方法中定义以下内容来构建SelectList

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

然后我在我的View 中呈现我的DropDownListFor 如下:

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

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

【问题讨论】:

不要这样做 - 它会导致问题(例如,您无法获得任何客户端验证) @StephenMuecke 为什么我不会得到任何客户端验证......现在我将 customerID 作为 int 并且它是必需的。默认情况下,我得到了客户端验证,当用户尝试提交表单时,他会收到需要 CustomerID 的错误...所以不确定我无法获得任何客户端验证是什么意思... 另一个问题是,如果在控制器中设置了CustomerID的值(即编辑和现有实体),在下拉列表中将无法正确选择。 @StephenMuecke 返回客户端验证.. 现在“请选择”的值将为空,因此客户端验证仍然有效.. 这是标记 @SeM,绝对不是。您不会获得客户端验证。 【参考方案1】:

您不应该为模型属性和ViewBag 属性使用相同的名称(理想情况下,您根本不应该使用ViewBag,而应该使用具有IEnumerable<SelectListItem> 属性的视图模型)。

当使用@Html.DropDownListFor(m => m.CustomerId, ....) 时,第一个"Please Select" 选项将始终被选中,即使模型属性的值已设置并匹配其中一个选项。原因是该方法首先根据您提供的IEnumerable<SelectListItem> 生成一个新的IEnumerable<SelectListItem>,以便设置Selected 属性的值。为了设置Selected 属性,它从ViewData 中读取CustomerID 的值,它找到的第一个是"IEnumerable<SelectListItem>"(不是模型属性的值)并且无法将该字符串与任何您的选项,因此选择了第一个选项(因为必须这样做)。

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

请参阅this DotNetFiddle,其中显示了可能用例的比较。只有对模型属性和ViewBag 属性使用不同的名称才能正常工作。

【讨论】:

小提琴错误,当我点击提交按钮时。它说“具有键 'CustomerA' 的 ViewData 项的类型为 'System.Int32' 但必须为 'IEnumerable' 类型。” @Saurabh,那是因为在返回视图(根据 GET 方法)之前,我没有在 POST 方法中重新填充 SelectLists - 但这不是小提琴的重点 - 它要显示如果您绑定到的属性和SelectList 使用相同的名称(如果您想了解有关该错误的更多详细信息 - 请参阅this question/answer【参考方案2】:

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

【讨论】:

@US3-57384 你能推荐更多吗? 看看我在我的代码中使用了什么。这解决了您的问题并且工作正常。 (IEnumerable)ViewBag.RT

以上是关于ViewBag 名称可以与 DropDownList 中的 Model 属性名称相同吗?的主要内容,如果未能解决你的问题,请参考以下文章

MVC DropDownLis 二级联动实现

可以从 Javascript 文件访问 MVC ViewBag 对象吗?

ViewBag 未在混合 Webforms/MVC 项目中声明

Asp.net MVC中的ViewData与ViewBag

MVC中获取来自控制器名称与动作的方法

值不能为null或为空。参数名称:contentPath