【问题标题】:Using ViewBag or calling service method on View在 View 上使用 ViewBag 或调用服务方法
【发布时间】: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


【解决方案1】:

这两个选项都不是一个好方法。考虑改用 ViewModel。

【讨论】:

  • 在Model中使用属性而不是直接调用服务方法有什么好处?我正在序列化我的模型对象以存储一段时间。如果我在 post 方法调用之前绑定这个新属性,将会有额外的数据,我应该清除它。如果我在发布之前没有绑定它,那么当出现错误或 modelState.IsValid 为 false 时,我应该在返回视图之前填充此属性。如果没有很大的理由我不能使用它,我不想努力管理它。
  • 对不起,我想我不明白你想要达到什么目的——你为什么要序列化你的 ViewModel?没关系,请考虑视图应该与服务层实现的业务逻辑完全无关。 View 只是一种虚拟的呈现机制,它通过 ViewModel 获取 Controller 提供的数据并显示数据。它是 MVC 架构的基础,我强烈建议遵循该架构本身就是走正确道路的一个很好的理由。
  • @Engineert 您应该有一个映射到 ViewModel 的数据模型,ViewModel 用于视图,而 Model 是您的数据模型,即 DTO
  • 好的,我知道了。谢谢。
【解决方案2】:

如前所述,使用视图模型来保存选择列表值

--部门视图模型

 [Required]
 public int DepartmentId { get; set; }
 public IEnumerable<SelectListItem> DepartmentSelectList { get; set; }

--部门控制器

 var vm = new DepartmentViewModel();
 vm.DepartmentSelectList = new DepartmentService().GetAll().Select(c => new SelectListItem
        {
            Text = c.DepartmentName,
            Value = c.Id.ToString()
        }).ToList();

--查看

 @Html.DropDownListFor(model => model.DepartmentId, model.DepartmentSelectList)

【讨论】:

  • 强类型视图使代码更简洁,更易于维护。您不需要来回进行显式转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 2015-02-28
  • 2010-12-24
  • 2015-05-06
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多