代码之家  ›  专栏  ›  技术社区  ›  granth

ASP.NET MVC ViewModel模式

  •  21
  • granth  · 技术社区  · 6 年前

    编辑: 我做了一些更好的 使用视图模型填充和读取视图中的数据 称之为 价值注入者 . http://valueinjecter.codeplex.com/

    它被使用 http://prodinner.codeplex.com -ASP.NET MVC示例应用程序

    您可以在Prodiner中看到使用ViewModel的最佳方法

    使用viewModel存储映射逻辑并不是一个好主意,因为存在重复和SRP冲突,但是现在有了valueinjecter,我有了干净的viewModel和干燥的映射代码。


    这是旧东西,不要用它:
    我制作了一个用于在ASP.NET MVC中编辑内容的ViewModel模式 当您必须创建一个用于编辑实体的表单,并且您必须在表单上放置一些下拉列表,以便用户选择一些值时,此模式非常有用。
        public class OrganisationBadViewModel
        {
            //paramterless constructor required, cuz we are gonna get an OrganisationViewModel object from the form in the post save method
            public OrganisationViewModel() : this(new Organisation()) {}
            public OrganisationViewModel(Organisation o)
            {
                Organisation = o;
                Country = new SelectList(LookupFacade.Country.GetAll(), "ID", "Description", CountryKey);  
            }       
            //that's the Type for whom i create the viewmodel
            public Organisation Organisation { get; set; }
    ...     
    
        }
    
    4 回复  |  直到 13 年前
        1
  •  9
  •   Dzmitry Huba    15 年前

    有几件事困扰着我。

    1. 术语。ViewModel就是这种情况,它是一个简单的视图数据,由控制器填充并稍后使用。View对控制器一无所知,因为ASP.NET MVC基础结构负责选择控制器和适当的操作。控制器处理用户交互。我认为它看起来更像被动视图,而不是视图模型(我假设通过视图模型,你的意思是模型视图视图模型模式)。

    2. 细节。填充视图数据的控制器不应该知道如何实现视图的详细信息。然而,OrganizationViewModel.Country公开了不必要的详细信息(SelectListItem是纯视图实现详细信息)。从而使控制器依赖于视图实现细节。我认为应该改变以避免它。考虑使用某个对象来保存某个国家的数据。

    希望这有帮助。

        2
  •  11
  •   Zhaph - Ben Duguid    15 年前

    这看起来非常类似WROX中的推荐做法。 Professional ASP.NET MVC 本书的第一章可从上述网址免费获得。

    从第100页开始,他们在 视图数据和视图模型 .

    当控制器类决定将HTML响应呈现回客户机时,它负责显式地将呈现响应所需的所有数据传递给视图模板。视图模板 不应该 执行任何数据检索或应用程序逻辑,而应将自己限制为仅具有由控制器传递给它的模型/数据驱动的呈现代码。

    […]

    使用[视图模型]模式时,我们创建强类型类,这些类针对特定的视图方案进行了优化,并公开了视图模板所需的动态值/内容的属性。然后,我们的控制器类可以填充这些视图优化类并将其传递给视图模板以供使用。这将在视图模板中启用类型安全性、编译时检查和编辑器智能感知。

    摘自Rob Connery等人在Wrox出版的专业ASP.NET MVC 1.0中的“第一章“书呆子晚餐”。原件可在 http://tinyurl.com/aspnetmvc

        3
  •  1
  •   Razzie    15 年前

    一般来说,我认为它看起来不错,并且通常是为域对象创建视图模型的好主意。

    我没有看过每一行代码,但有一件事引起了我的注意,那就是OrganizationViewModel的构造函数。我用以下方法重写它:

    public OrganisationViewModel() : this(new Organisation()) { }
    
    public OrganisationViewModel(Organisation o)
    {
      Organisation = o;
      InitCollections();
    }
    

    这会删除一些重复的代码,因为您不必调用 InitCollections() 在两个构造函数中。当然,这只是一个小细节,与总体思路无关。

        4
  •  1
  •   Beep beep    15 年前

    我们开始这样做,但是我们的控制器开始变得可怕(因为我们的视图模型不一定是以1:1的比例映射到我们的数据库)。为了减轻这一点,我们创建了创建视图模型的映射器类,然后映射回为数据库绑定的数据。然后,控制器只调用映射器类方法。似乎工作得很好。