ViewBag vs Model,在MVC.NET中

时间:2014-02-12 01:42:42

标签: asp.net-mvc viewbag asp.net-mvc-viewmodel

这更像是一个通用的架构问题:

我正在尝试决定我的程序员是否可以使用“ViewBags”将数据传递给已经接受模型的视图。

我个人的偏好是避免使用ViewBags并构建包含视图所需的所有数据的健壮模型:

方法1:

MODEL A: 
- List of Employees
- Nullable integer, indicating which item from the list is currently selected
- string firstName (empty if index is null)
- string lastname (empty if index is null)

方法2:

MODEL A: 
- List of Employees

ViewBag:
- ViewBag.Index (indicating which item from the list is currently selected)
- ViewBag.FirstName
- ViewBag.LastName

任何人都可以想到为什么Approach2会比接近1更好吗?

感谢您的输入

5 个答案:

答案 0 :(得分:16)

在我看来,你应该 从不使用 ViewBag 而没有非常好的理由Brad Thomas' answer指出了其中一个很好的理由的罕见例子。

假设您有一个由整个网站共享的主人layout(或partial view)和几十个强类型的视图,每个视图都有自己的模型。如何将数据传递给布局?我见过的一些策略:

  1. 将布局属性添加到每个模型。
  2. 如果你没有很多型号,或者它只有一两个额外的属性,这可能会有效。这很快就会成为维护的噩梦。

    1. 让所有模型都从包含布局数据的类继承。
    2. 我避免创建ModelBase类,但有时可能是必要的。

      1. 为布局和通用模型基类创建模型。
      2. 我见过MVC应用程序,其中包含任何视图都可以使用的几种布局。如果模型继承自基类,则可能需要为每个布局都有一个基类。为了避免重复工作,我将为每个布局创建一个布局模型。那么这样的事情可能适合你:

        abstract class ModelBase<TLayout> {
            public TLayout Layout { get; set; }
        }
        
        class Model : ModelBase<LayoutModel2> { /* model stuff here */ } 
        
        1. 将布局属性放入 ViewBag
        2. 在极少数情况下我可以想象将布局信息放在模型中是不是正确的调用。人们使用他们的域模型作为他们的模型似乎很平常,例如,您可能不希望将布局/视图数据与业务/域数据混合在一起。

          如果您决定使用ViewBag,请避免这样做:

          ViewBag.Title = "My page"
          ViewBag.UserID = 123
          ViewBag.UserName = "admin"
          ViewBag.UserDisplayName = "Administrator"
          

          存在明显的潜在问题,例如在不同的地方使用不同的大写(例如UserId而不是UserID)。不太明显的是,有人可能会意外地将ViewBag.UserID设置为stringNullable<int>

          class SomeOtherClass {
              public string UserID { get; set; } // someone uses a string...
          }
          
          ViewBag.UserID = someOtherClassObj.UserID; // now you're in trouble.
          

          因此,如果您必须使用ViewBag,我建议您这样做:

          ViewBag.LayoutModel = new LayoutModel { UserID = User.ID, UserName = User.Name };
          

答案 1 :(得分:5)

我个人会选择Model作为参数,因为model是强类型的,所以当它传递给view时,我们也可以控制我们的参数在field关键字中是否有效。 模型是未来代码维护的最佳方式。

参考:

Avoid Viewbag

答案 2 :(得分:4)

将信息传递给视图的布局

答案 3 :(得分:2)

你能用吗?当然。你应该用吗?取决于你还想做什么。通常您会看到ViewBag保留用于发送数据,如页面标题或其他类似的效果。您可能希望保留模型中数据库中填充的参数。主要是因为模型绑定以及您是否想要执行模型验证。

答案 4 :(得分:1)

这取决于场景是什么,如果想要传递的字段将仅用于此特定视图,并且它们可能不是作为实体或模型的一部分而制作,那么我将使用viewbags,否则我将使用它模特。