我是ASP的新手。净MVC。我在理解ViewModel的目的方面有一个问题。

什么是ViewModel,为什么我们需要一个ASP的ViewModel。NET MVC应用程序?

如果我能给出一个关于它的工作和解释的好例子,那就更好了。


当前回答

ViewModel是一种解决MVC框架概念上的缺陷的方法。它代表了三层模型-视图-控制器体系结构中的第四层。当Model(域模型)不合适,对于View来说太大(大于2-3个字段)时,我们创建一个更小的ViewModel来传递给View。

其他回答

视图模型是一个类,我们可以使用它在视图上呈现数据。假设您有两个实体Place和PlaceCategory,并且您希望使用一个模型访问来自这两个实体的数据,那么我们使用ViewModel。

public class Place
    {
       public int PlaceId { get; set; }
        public string PlaceName { get; set; }
        public string Latitude { get; set; }
        public string Longitude { get; set; }
        public string BestTime { get; set; }
    }
    public class Category
    {
        public int ID { get; set; }
        public int? PlaceId { get; set; }
        public string PlaceCategoryName { get; set; }
        public string PlaceCategoryType { get; set; }
    }
    public class PlaceCategoryviewModel
    {
        public string PlaceName { get; set; }
        public string BestTime { get; set; }
        public string PlaceCategoryName { get; set; }
        public string PlaceCategoryType { get; set; }
    }

在上面的例子中,Place和Category是两个不同的实体,PlaceCategory ViewModel是我们可以在View上使用的ViewModel。

视图模型是表示特定视图中使用的数据模型的类。我们可以使用这个类作为登录页面的模型:

public class LoginPageVM
{
    [Required(ErrorMessage = "Are you really trying to login without entering username?")]
    [DisplayName("Username/e-mail")]
    public string UserName { get; set; }
    [Required(ErrorMessage = "Please enter password:)")]
    [DisplayName("Password")]
    public string Password { get; set; }
    [DisplayName("Stay logged in when browser is closed")]
    public bool RememberMe { get; set; }
}

使用这个视图模型,你可以定义视图(Razor视图引擎):

@model CamelTrap.Models.ViewModels.LoginPageVM

@using (Html.BeginForm()) {
    @Html.EditorFor(m => m);
    <input type="submit" value="Save" class="submit" />
}

和行动:

[HttpGet]
public ActionResult LoginPage()
{
    return View();
}

[HttpPost]
public ActionResult LoginPage(LoginPageVM model)
{
    ...code to login user to application...
    return View(model);
}

产生这个结果(提交表单后,屏幕显示验证消息):

正如你所看到的,视图模型有很多角色:

视图模型通过只包含在视图中表示的字段来记录视图。 视图模型可能包含使用数据注释或IDataErrorInfo的特定验证规则。 视图模型定义了视图的外观(对于LabelFor,EditorFor,DisplayFor helper)。 视图模型可以组合来自不同数据库实体的值。 你可以很容易地为视图模型指定显示模板,并使用DisplayFor或EditorFor helper在许多地方重用它们。

视图模型及其检索的另一个示例:我们希望显示基本用户数据、他的权限和用户名。我们创建一个特殊的视图模型,它只包含必需的字段。我们从数据库的不同实体中检索数据,但是视图只知道视图模型类:

public class UserVM {
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsAdministrator { get; set; }
    public string MothersName { get; set; }
}

检索:

var user = db.userRepository.GetUser(id);

var model = new UserVM() {
   ID = user.ID,
   FirstName = user.FirstName,
   LastName = user.LastName,
   IsAdministrator = user.Proviledges.IsAdministrator,
   MothersName = user.Mother.FirstName + " " + user.Mother.LastName
} 

视图模型a是一个简单的类,它可以包含多个类属性。我们使用它来继承所有必需的属性,例如,我有两个类Student和Subject

Public class Student
{
public int Id {get; set;}
public string Name {get; set;}
}  
Public class Subject
{
public int SubjectID {get; set;}
public string SubjectName {get; set;}
}

现在我们想要在视图(MVC)中显示记录学生的名字和科目的名字,但不可能添加多个类,如:

 @model ProjectName.Model.Student  
 @model ProjectName.Model.Subject

上面的代码将抛出一个错误…

现在我们创建了一个类,可以给它起任何名字,但是这种格式“XyzViewModel”会让它更容易理解。这是继承的概念。 现在我们创建第三个类,名称如下:

public class StudentViewModel:Subject
{
public int ID {get; set;}
public string Name {get; set;}
}

现在我们在View中使用这个ViewModel

@ model ProjectName.Model.StudentViewModel

现在我们能够在View中访问StudentViewModel和继承类的所有属性。

如果您有特定于视图的属性,并且与DB/Service/Data存储无关,那么使用ViewModels是一个很好的实践。比方说,您希望根据一个(或两个)DB字段选择一个复选框,但DB字段本身不是布尔值。虽然可以在模型本身中创建这些属性,并将其隐藏在数据绑定中,但您可能不希望根据此类字段和事务的数量使模型变得混乱。

如果特定于视图的数据和/或转换太少,您可以使用模型本身

视图模型与您的数据模型相同,但您可以在其中添加2个或更多数据模型类。根据这一点,你必须改变你的控制器,一次采取2个模型