MVC ASP.NET中的ViewData和ViewModel

10

我是.Net开发新手,现在正在跟随NerdDinner教程学习。不知道有没有人能告诉我ViewData和ViewModel之间的区别(我只知道它们都用于从控制器传递数据到视图),并且在什么情况下应该使用ViewData而不是ViewModel,反之亦然。

提前感谢!

Sally

注:ViewData和ViewModel都是ASP.NET MVC框架中用于将数据从控制器传递到视图的机制。它们的主要区别在于ViewModel是一个具有显式类型声明的模型对象,可以帮助在编译时检测类型错误;而ViewData是一个动态对象,无法在编译时检测类型错误。一般来说,如果需要将多个相关数据项传递给视图,则应使用ViewModel,否则可以使用ViewData。
2个回答

12

什么是ViewData?

  • 它是一个字典对象,您可以将数据放入其中,然后该数据可供视图使用。

ViewData示例

控制器操作方法可能如下:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var featuredProduct = new Product
        {
            Name = "Smart Phone",
            QtyOnHand = 12
        };

        ViewData["FeaturedProduct"] = featuredProduct;
        return View();
    }
}

如何在视图中使用ViewData?

@{    
    var viewDataProduct = ViewData["FeaturedProduct"] as Product;
 }
<div>
    Today's Featured Product is!
    <h3>@viewDataProduct.Name</h3>
</div>

什么是ViewModel?

  • 允许您从一个或多个数据模型或源中塑造多个实体成为一个单一对象
  • 优化以便视图进行使用和呈现

它就像:

View Model image

如何在MVC 3中使用ViewModel?

领域模型

public class Product
    {
        public Product() { Id = Guid.NewGuid(); Created = DateTime.Now; }
        public Guid Id { get; set; }
        public string ProductName { get; set; }
    }

视图模型

public class ProductViewModel
    {
        public Guid VmId { get; set; }

        [Required(ErrorMessage = "required")]
        public string ProductName { get; set; }

    }

控制器操作方法

[HttpGet]
public ActionResult AddProduct()
{
    //for initialize viewmodel
    var productViewModel = new ProductViewModel();

    //assign values for viewmodel
    productViewModel.ProductName = "Smart Phone";

    //send viewmodel into UI (View)
    return View("AddProduct", productViewModel);
}

查看 - AddProduct.cshtml

@model YourProject.ViewModels.ProductViewModel //set your viewmodel here

结论

  • 使用ViewModel能够将强类型数据传递到View中
  • 但是ViewData是松散类型,因此需要在View上进行数据类型转换
  • ViewModel可用于复杂情况,例如合并两个以上的领域模型
  • 但ViewData仅适用于简单情况,如为下拉列表带来数据
  • ViewModel可用于基于属性的验证场景,这对UI很重要
  • 但不能使用ViewData进行此类验证
  • 作为最佳实践,始终尝试在视图中使用强类型数据。ViewModel是最佳选择。

1
我经常觉得将所需的领域模型加载到ViewModel中作为私有成员更加清晰,并通过属性向视图公开实际需要的内容。另外,如果像适配器一样设置,从ViewModel通过视图返回的数据可以反过来填充隐藏领域对象的数据。 - Sinaesthetic

8

ViewData:

简而言之,将ViewData用作辅助数据,例如SelectList的数据源。

ViewModel:

ASP.NET MVC ViewModel模式

当Controller类决定向客户端呈现HTML响应时,它负责显式地向视图模板传递呈现响应所需的所有数据。视图模板不应执行任何数据检索或应用程序逻辑 - 而应仅限于根据控制器传递给它的模型/数据驱动其渲染代码。

[...]

使用[“ViewModel”]模式时,我们创建针对特定视图场景进行优化的强类型类,并公开用于视图模板所需的动态值/内容的属性。然后,我们的控制器类可以填充并传递这些针对视图进行优化的类以供视图模板使用。这样可以实现类型安全、编译时检查和编辑器智能感知在视图模板内部。


感谢您的回答,如果有人需要了解更多关于这个话题的信息,我也发现了一篇很棒的博客文章与我的问题相关:http://theminimalistdeveloper.com/2010/08/21/why-when-and-how-to-use-typed-views-and-viewmodel-pattern-in-asp-net-mvc/ - Amy Lee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接