【发布时间】:2016-01-14 12:44:43
【问题描述】:
我想知道在 View 上填充 SelectList 时应该使用什么。我知道有两种方法可以做到这一点。 第一的; 在控制器的 get 方法上设置 ViewBag。
ViewBag.DepartmentList = new SelectList(_departmentService.GetAll(), "Id", "Name", selectedValue: user.DepartmentId);
然后在视图上使用它(你也可以使用 ViewData)
@Html.DropDownListFor(model => model.DepartmentId, (IEnumerable<SelectListItem>)ViewBag.DepartmentList )
我知道的第二种方法是直接从视图中调用服务方法:
@Html.DropDownListFor(model=>model.DepartmentId,new SelectList((new DepartmentService()).GetAll(),"Id","Name", selectedValue: Model.DepartmentId ))
所以,有时我们应该返回视图将模型传递给控制器 post 方法上的方法,尤其是出现错误或 ModelState 无效。如您所知,在执行此 ViewBag.DepartmentList 时,应再次使用 post 方法填充。另一方面,使用第二种方式,无论是 get 和 post 方法,都不需要创建和填充 ViewBag.DepartmentList。但我想知道是否有任何区别或我应该使用哪一个?为什么?
【问题讨论】:
-
两者都不推荐,你应该在你的 ViewModel 中有一个属性
-
这有什么原因吗?
-
这是违反MVC模式的,在view中查询你的数据源,View的职责就是渲染html,在controller中做取东西,你的view应该只是做渲染html的逻辑
-
当然是有原因的。 ViewBag 是一种凌乱的动态对象,而 ViewModel 是定义良好的对象,它包含您的 View 需要的所有数据。您也提到了 TempData - 它们的用途完全不同,它们用于在两个请求之间传递数据,而不是在控制器和视图之间传递数据。另一种选择是从视图调用服务是一种反模式。想都别想 :)。
-
ViewBag 可能包含与特定视图无关的少量数据。比方说,嗯,MVC 过滤器(而不是控制器)需要存储一些一般数据,这些数据可能会或可能不会被页面上的某个视图或部分视图使用。目前我还没有想到具体的例子,但是如果你阅读微软的一些教程,你会发现他们使用 ViewBag 来存储页面标题。
标签: c# asp.net-mvc-5 service-layer