asp.net-mvc MVC 中的 ViewModel 是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11064316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is ViewModel in MVC?
提问by unique
I am new to ASP.NET MVC. I have a problem with understanding the purpose of a ViewModel.
我是 ASP.NET MVC 的新手。我在理解 ViewModel 的用途时遇到问题。
What is a ViewModel and why do we need a ViewModel for an ASP.NET MVC Application?
什么是 ViewModel,为什么我们需要一个用于 ASP.NET MVC 应用程序的 ViewModel?
If I get a good example about its working and explanation that would be better.
如果我能得到一个关于它的工作和解释的好例子,那就更好了。
回答by Brendan Vogt
A view modelrepresents the data that you want to display on your view/page, whether it be used for static text or for input values (like textboxes and dropdown lists) that can be added to the database (or edited). It is something different than your domain model. It is a model for the view.
Aview model表示您想要在视图/页面上显示的数据,无论它是用于静态文本还是用于可以添加到数据库(或编辑)的输入值(如文本框和下拉列表)。它与您的domain model. 它是视图的模型。
Let us say that you have an Employeeclass that represents your employee domain model and it contains the following properties (unique identifier, first name, last name and date created):
假设您有一个Employee代表您的员工域模型的类,它包含以下属性(唯一标识符、名字、姓氏和创建日期):
public class Employee : IEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateCreated { get; set; }
}
View models differ from domain models in that view models only contain the data (represented by properties) that you want to use on your view. For example, lets say that you want to add a new employee record, your view model might look like this:
视图模型与域模型的不同之处在于,视图模型仅包含您要在视图上使用的数据(由属性表示)。例如,假设您要添加新员工记录,您的视图模型可能如下所示:
public class CreateEmployeeViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
As you can see it only contains two of the properties. These two properties are also in the employee domain model. Why is this you may ask? Idmight not be set from the view, it might be auto generated by the Employee table. And DateCreatedmight also be set in the stored procedure or in the service layer of your application. So Idand DateCreatedare not needed in the view model. You might want to display these two properties when you view an employee's details (an employee that has already been captured) as static text.
如您所见,它仅包含两个属性。这两个属性也在员工域模型中。你可能会问这是为什么? Id可能不是从视图中设置的,它可能是由 Employee 表自动生成的。并且DateCreated也可能在存储过程或应用程序的服务层中设置。因此Id,DateCreated在视图模型中不需要和。当您以静态文本形式查看员工的详细信息(已捕获的员工)时,您可能希望显示这两个属性。
When loading the view/page, the create action method in your employee controller will create an instance of this view model, populate any fields if required, and then pass this view model to the view/page:
加载视图/页面时,员工控制器中的 create action 方法将创建此视图模型的实例,如果需要填充任何字段,然后将此视图模型传递给视图/页面:
public class EmployeeController : Controller
{
private readonly IEmployeeService employeeService;
public EmployeeController(IEmployeeService employeeService)
{
this.employeeService = employeeService;
}
public ActionResult Create()
{
CreateEmployeeViewModel model = new CreateEmployeeViewModel();
return View(model);
}
public ActionResult Create(CreateEmployeeViewModel model)
{
// Do what ever needs to be done before adding the employee to the database
}
}
Your view/page might look like this (assuming you are using ASP.NET MVCand the Razorview engine):
您的视图/页可能是这样的(假设你正在使用ASP.NET MVC和Razor视图引擎):
@model MyProject.Web.ViewModels.CreateEmployeeViewModel
<table>
<tr>
<td><b>First Name:</b></td>
<td>@Html.TextBoxFor(m => m.FirstName, new { maxlength = "50", size = "50" })
@Html.ValidationMessageFor(m => m.FirstName)
</td>
</tr>
<tr>
<td><b>Last Name:</b></td>
<td>@Html.TextBoxFor(m => m.LastName, new { maxlength = "50", size = "50" })
@Html.ValidationMessageFor(m => m.LastName)
</td>
</tr>
</table>
Validation would thus be done only on FirstNameand LastName. Using FluentValidationyou might have validation like this:
因此,验证将仅在FirstName和上完成LastName。使用FluentValidation你可能有这样的验证:
public class CreateEmployeeViewModelValidator : AbstractValidator<CreateEmployeeViewModel>
{
public CreateEmployeeViewModelValidator()
{
RuleFor(m => m.FirstName)
.NotEmpty()
.WithMessage("First name required")
.Length(1, 50)
.WithMessage("First name must not be greater than 50 characters");
RuleFor(m => m.LastName)
.NotEmpty()
.WithMessage("Last name required")
.Length(1, 50)
.WithMessage("Last name must not be greater than 50 characters");
}
}
And with Data Annotations it might look this:
使用数据注释,它可能看起来像这样:
public class CreateEmployeeViewModel : ViewModelBase
{
[Display(Name = "First Name")]
[Required(ErrorMessage = "First name required")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required(ErrorMessage = "Last name required")]
public string LastName { get; set; }
}
The key thing to remember is that the view model only represents the data that you want to use, nothing else. You can imagine all the unnecessary code and validation if you have a domain model with 30 properties and you only want to update a single value. Given this scenario you would only have this one value/property in the view model and not all the properties that are in the domain object.
要记住的关键是视图模型只表示您想要使用的数据,没有别的。如果您有一个包含 30 个属性的域模型并且您只想更新一个值,您可以想象所有不必要的代码和验证。在这种情况下,您在视图模型中只会有这个值/属性,而不是域对象中的所有属性。
A view model might not only have data from one database table. It can combine data from another table. Take my example above about adding a new employee record. Besides adding just the first and last names you might also want to add the department of the employee. This list of departments will come from your Departmentstable. So now you have data from the Employeesand Departmentstables in one view model. You will just then need to add the following two properties to your view model and populate it with data:
视图模型可能不仅具有来自一个数据库表的数据。它可以合并来自另一个表的数据。以我上面关于添加新员工记录的示例为例。除了只添加名字和姓氏之外,您可能还想添加员工所在的部门。此部门列表将来自您的Departments表。所以现在您在一个视图模型中拥有来自Employees和Departments表的数据。然后您需要将以下两个属性添加到您的视图模型并用数据填充它:
public int DepartmentId { get; set; }
public IEnumerable<Department> Departments { get; set; }
When editing employee data (an employee that has already been added to the database) it wouldn't differ much from my example above. Create a view model, call it for example EditEmployeeViewModel. Only have the data that you want to edit in this view model, like first name and last name. Edit the data and click the submit button. I wouldn't worry too much about the Idfield because the Idvalue will probably been in the URL, for example:
在编辑员工数据(已添加到数据库中的员工)时,它与我上面的示例没有太大区别。创建一个视图模型,例如调用它EditEmployeeViewModel。在这个视图模型中只有你想要编辑的数据,比如名字和姓氏。编辑数据并单击提交按钮。我不会太担心该Id字段,因为该Id值可能会在 URL 中,例如:
http://www.yourwebsite.com/Employee/Edit/3
Take this Idand pass it through to your repository layer, together with your first name and last name values.
借此Id并通过与您的名字和姓氏值传递到您的存储库层,在一起。
When deleting a record, I normally follow the same path as with the edit view model. I would also have a URL, for example:
删除记录时,我通常遵循与编辑视图模型相同的路径。我也会有一个 URL,例如:
http://www.yourwebsite.com/Employee/Delete/3
When the view loads up for the first time I would get the employee's data from the database using the Idof 3. I would then just display static text on my view/page so that the user can see what employee is being deleted. When the user clicks the Delete button, I would just use the Idvalue of 3 and pass it to my repository layer. You only need the Idto delete a record from the table.
当视图第一次加载时,我会使用Id3从数据库中获取员工的数据。然后我将只在我的视图/页面上显示静态文本,以便用户可以看到正在删除的员工。当用户单击“删除”按钮时,我只会使用Id值 3 并将其传递给我的存储库层。您只需Id要从表中删除一条记录。
Another point, you don't really need a view model for every action. If it is simple data then it would be fine to only use EmployeeViewModel. If it is complex views/pages and they differ from each other then I would suggest you use separate view models for each.
另一点,您并不是真的需要每个动作的视图模型。如果它是简单的数据,那么只使用EmployeeViewModel. 如果它是复杂的视图/页面并且它们彼此不同,那么我建议您为每个视图使用单独的视图模型。
I hope this clears up any confusion that you had about view models and domain models.
我希望这能消除您对视图模型和域模型的任何混淆。
回答by LukLed
View modelis a class that represents the data model used in a specific view. We could use this class as a model for a login page:
视图模型是表示特定视图中使用的数据模型的类。我们可以使用这个类作为登录页面的模型:
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; }
}
Using this view model you can define the view (Razor view engine):
使用此视图模型,您可以定义视图(Razor 视图引擎):
@model CamelTrap.Models.ViewModels.LoginPageVM
@using (Html.BeginForm()) {
@Html.EditorFor(m => m);
<input type="submit" value="Save" class="submit" />
}
And actions:
和行动:
[HttpGet]
public ActionResult LoginPage()
{
return View();
}
[HttpPost]
public ActionResult LoginPage(LoginPageVM model)
{
...code to login user to application...
return View(model);
}
Which produces this result (screen is taken after submitting form, with validation messages):
产生这个结果(在提交表单后截取屏幕,带有验证消息):


As you can see, a view model has many roles:
如您所见,视图模型有许多角色:
- View models documents a view by consisting only fields, that are represented in view.
- View models may contain specific validation rules using data annotations or IDataErrorInfo.
- View model defines how a view should look (for
LabelFor,EditorFor,DisplayForhelpers). - View models can combine values from different database entities.
- You can specify easily display templates for view models and reuse them in many places using DisplayFor or EditorFor helpers.
- 视图模型通过仅包含在视图中表示的字段来记录视图。
- 视图模型可能包含使用数据注释或 IDataErrorInfo 的特定验证规则。
- 视图模型定义了视图的外观(对于
LabelFor、EditorFor、DisplayFor助手)。 - 视图模型可以组合来自不同数据库实体的值。
- 您可以轻松地为视图模型指定显示模板,并使用 DisplayFor 或 EditorFor 助手在许多地方重用它们。
Another example of a view model and its retrieval: We want to display basic user data, his privileges and users name. We create a special view model, which contains only the required fields. We retrieve data from different entities from database, but the view is only aware of the view model class:
视图模型及其检索的另一个示例:我们希望显示基本用户数据、他的权限和用户名。我们创建了一个特殊的视图模型,它只包含必填字段。我们从数据库中检索不同实体的数据,但视图只知道视图模型类:
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; }
}
Retrieval:
恢复:
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
}
回答by Sam
Edit: I updated this answer on my Blog:
编辑:我在我的博客上更新了这个答案:
http://www.samwheat.com/post/The-function-of-ViewModels-in-MVC-web-development
http://www.samwheat.com/post/The-function-of-ViewModels-in-MVC-web-development
My answer is a bit lengthy but I think it is important to compare view models to other types of commonly used models to understand why they are different and why they are necessary.
我的回答有点冗长,但我认为将视图模型与其他类型的常用模型进行比较以了解它们为何不同以及为何它们是必要的很重要。
To summarize, and to directly answer the question that is asked:
总结一下,并直接回答提出的问题:
Generally speaking, a view model is an object that contains all the properties and methods necessary to render a view. View model properties are often related to data objects such as customers and orders and in addition they also contain properties related to the page or application itself such as user name, application name etc. View models provide a convenient object to pass to a rendering engine to create a html page. One of many reasons to use a view model is that view models provide a way to unit test certain presentation tasks such as handling user input, validating data, retrieving data for display, etc.
一般来说,视图模型是一个包含渲染视图所需的所有属性和方法的对象。视图模型属性通常与数据对象(例如客户和订单)相关,此外它们还包含与页面或应用程序本身相关的属性,例如用户名、应用程序名称等。视图模型提供了一个方便的对象来传递给渲染引擎以创建一个html页面。使用视图模型的众多原因之一是,视图模型提供了一种对某些表示任务进行单元测试的方法,例如处理用户输入、验证数据、检索数据以进行显示等。
Here is a comparison of Entity models (a.ka. DTO's a.ka. models), Presentation Models, and View Models.
这是实体模型(又名 DTO 的又名模型)、表示模型和视图模型的比较。
Data Transfer Objects a.k.a “Model”
数据传输对象又名“模型”
A Data Transfer Object (DTO) is a class with properties that match a table schema in a database. DTO's are named for their common usage for shuttling data to and from a data store.
Characteristics of DTO's:
数据传输对象 (DTO) 是一个类,其属性与数据库中的表模式相匹配。DTO 以其在数据存储之间穿梭数据的常见用途而命名。
DTO的特点:
? Are business objects – their definition is dependent on application data.
? 是业务对象——它们的定义取决于应用程序数据。
? Usually contain properties only – no code.
? 通常只包含属性——没有代码。
? Primarily used for transporting data to and from a database.
? 主要用于在数据库之间传输数据。
? Properties exactly or closely match fields on a specific table in a data store.
? 属性与数据存储中特定表上的字段完全或紧密匹配。
Database tables are usually normalized therefore DTO's are usually normalized also. This makes them of limited use for presenting data. However, for certain simple data structures they often do quite well.
数据库表通常被规范化,因此 DTO 通常也被规范化。这使得它们在呈现数据方面的用途有限。然而,对于某些简单的数据结构,它们通常做得很好。
Here are two examples of what DTO's might look like:
以下是 DTO 可能是什么样子的两个示例:
public class Customer
{
public int ID { get; set; }
public string CustomerName { get; set; }
}
public class Order
{
public int ID { get; set; }
public int CustomerID { get; set; }
public DateTime OrderDate { get; set; }
public Decimal OrderAmount { get; set; }
}
?
?
Presentation Models
演示模型
A presentation model is a utilityclass that is used to render data on a screen or report. Presentation models are typically used to model complex data structures that are composed from data from multiple DTO's. Presentation models often represent a denormalized view of data.
表示模型是用于在屏幕或报告上呈现数据的实用程序类。表示模型通常用于对由来自多个 DTO 的数据组成的复杂数据结构进行建模。表示模型通常表示数据的非规范化视图。
Characteristics of Presentation Models:
演示模型的特点:
? Are business objects – their definition is dependent on application data.
? 是业务对象——它们的定义取决于应用程序数据。
? Contain mostly properties. Code is typically limited to formatting data or converting to or from a DTO. Presentation Models should not contain business logic.
? 主要包含属性。代码通常仅限于格式化数据或转换为 DTO 或从 DTO 转换。表示模型不应包含业务逻辑。
? Often present a denormalized view of data. That is, they often combine properties from multiple DTO's.
? 通常呈现非规范化的数据视图。也就是说,它们通常组合来自多个 DTO 的属性。
? Often contain properties of a different base type than a DTO. For example dollar amounts may be represented as strings so they can contain commas and a currency symbol.
? 通常包含与 DTO 不同的基本类型的属性。例如,美元金额可以表示为字符串,因此它们可以包含逗号和货币符号。
? Often defined by how they are used as well as their object characteristics. In other words, a simple DTO that is used as the backing model for rendering a grid is in fact also a presentation model in the context of that grid.
? 通常由它们的使用方式以及它们的对象特性来定义。换句话说,用作渲染网格的支持模型的简单 DTO 实际上也是该网格上下文中的表示模型。
Presentation models are used “as needed” and “where needed” (whereas DTO's are usually tied to the database schema). A presentation model may be used to model data for an entire page, a grid on a page, or a dropdown on a grid on a page. Presentation models often contain properties that are other presentation models. Presentation models are often constructed for a single-use purpose such as to render a specific grid on a single page.
表示模型在“需要时”和“需要时”使用(而 DTO 通常与数据库模式相关联)。演示模型可用于为整个页面、页面上的网格或页面上的网格上的下拉菜单建模数据。表示模型通常包含其他表示模型的属性。演示模型通常是为一次性目的而构建的,例如在单个页面上呈现特定网格。
An example presentation model:
示例演示模型:
public class PresentationOrder
{
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public string PrettyDate { get { return OrderDate.ToShortDateString(); } }
public string CustomerName { get; set; }
public Decimal OrderAmount { get; set; }
public string PrettyAmount { get { return string.Format("{0:C}", OrderAmount); } }
}
View Models
查看模型
A view model is similar to a presentation model in that is a backing class for rendering a view. However it is very different from a Presentation Model or a DTO in how it is constructed. View models often contain the same properties as presentation models and DTO's and for this reason they are often confused one for the other.
视图模型类似于表示模型,因为它是用于呈现视图的支持类。然而,它在构建方式上与 Presentation Model 或 DTO 有很大不同。视图模型通常包含与表示模型和 DTO 相同的属性,因此它们经常被混淆。
Characteristics of View Models:
视图模型的特点:
? Are the single source of data used to render a page or screen. Usually this means that a view model will expose every property that any control on the page will need to render itself correctly. Making the view model the single source of data for the view greatly improves its capability and value for unit testing.
? 是用于呈现页面或屏幕的单一数据源。通常这意味着视图模型将公开页面上的任何控件需要正确呈现自身的每个属性。使视图模型成为视图的单一数据源,极大地提高了其单元测试的能力和价值。
? Are composite objectsthat contain properties that consist of application data as well as properties that are used by application code. This characteristic is crucial when designing the view model for reusability and is discussed in the examples below.
? 是包含由应用程序数据以及应用程序代码使用的属性组成的属性的复合对象。在为可重用性设计视图模型时,此特性至关重要,并将在下面的示例中进行讨论。
? Contain application code. View Models usually contain methods that are called during rendering and when the user is interacting with the page. This code typically relates to event handling, animation, visibility of controls, styling, etc.
? 包含应用程序代码。视图模型通常包含在呈现期间以及用户与页面交互时调用的方法。此代码通常与事件处理、动画、控件可见性、样式等有关。
? Contain code that calls business services for the purpose of retrieving data or sending it to a database server. This code is often mistakenly placed in a controller. Calling business services from a controller usually limits the usefulness of the view model for unit testing. To be clear, view models themselves should not contain business logic but should make calls to services which do contain business logic.
? 包含调用业务服务以检索数据或将其发送到数据库服务器的代码。这段代码经常被错误地放在控制器中。从控制器调用业务服务通常会限制视图模型在单元测试中的实用性。需要明确的是,视图模型本身不应该包含业务逻辑,而应该调用包含业务逻辑的服务。
? Often contain properties which are other view models for other pages or screens.
? 通常包含其他页面或屏幕的其他视图模型的属性。
? Are written “per page” or “per screen”. A unique View Model is typically written for every page or screen in an application.
? 写成“每页”或“每屏”。一个独特的视图模型通常是为应用程序中的每个页面或屏幕编写的。
? Usually derive from a base class since most pages and screens share common properties.
? 通常从基类派生,因为大多数页面和屏幕共享公共属性。
View Model Composition
查看模型组合
As stated earlier, view models are composite objects in that they combine application properties and business data properties on a single object. Examples of commonly used application properties that are used on view models are:
如前所述,视图模型是复合对象,因为它们在单个对象上组合了应用程序属性和业务数据属性。用于视图模型的常用应用程序属性示例有:
? Properties that are used to display application state such as error messages, user name, status, etc.
? 用于显示应用程序状态的属性,例如错误消息、用户名、状态等。
? Properties used to format, display, stylize, or animate controls.
? 用于格式化、显示、风格化或动画控件的属性。
? Properties used for data binding such as list objects and properties that hold intermediate data that is input by the user.
? 用于数据绑定的属性,例如列表对象和保存用户输入的中间数据的属性。
The following examples show why the composite nature of view models is important and how we can best construct a View Model that efficient and reusable.
以下示例说明了为什么视图模型的复合性质很重要,以及我们如何最好地构建一个高效且可重用的视图模型。
Assume we are writing a web application. One of the requirements of the application design is that the page title, user name, and application name must be displayed on every page. If we want to create a page to display a presentation order object, we may modify the presentation model as follows:
假设我们正在编写一个 Web 应用程序。应用程序设计的要求之一是页面标题、用户名和应用程序名称必须显示在每个页面上。如果我们要创建一个页面来展示一个展示订单对象,我们可以修改展示模型如下:
public class PresentationOrder
{
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public string PrettyDate { get { return OrderDate.ToShortDateString(); } }
public string CustomerName { get; set; }
public Decimal OrderAmount { get; set; }
public string PrettyAmount { get { return string.Format("{0:C}", OrderAmount); } }
}
This design might work… but what if we want to create a page that will display a list of orders? The PageTitle, UserName, and ApplicationName properties will be repeated and become unwieldy to work with. Also, what if we want to define some page-level logic in the constructor of the class? We can no longer do that if we create an instance for every order that will be displayed.
这种设计可能可行……但是如果我们想创建一个显示订单列表的页面怎么办?PageTitle、UserName 和 ApplicationName 属性将重复并变得难以使用。另外,如果我们想在类的构造函数中定义一些页面级逻辑怎么办?如果我们为将要显示的每个订单创建一个实例,我们就不能再这样做了。
Composition over inheritance
组合优于继承
Here is a way we might re-factor the order presentation model such that it become a true view model and will be useful for displaying a single PresentationOrder object or a collection of PresentationOrder objects:
这是我们可以重构订单表示模型的一种方法,使其成为真正的视图模型,并且对于显示单个 PresentationOrder 对象或 PresentationOrder 对象的集合很有用:
public class PresentationOrderVM
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business properties
public PresentationOrder Order { get; set; }
}
public class PresentationOrderVM
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business properties
public List<PresentationOrder> Orders { get; set; }
}
Looking at the above two classes we can see that one way to think about a view model is that it is a presentation model that contains another presentation model as a property. The top level presentation model (i.e. view model) contains properties that are relevant to the page or application while presentation model (property) contains properties that are relevant to application data.
查看以上两个类,我们可以看到考虑视图模型的一种方式是它是一个表示模型,其中包含另一个表示模型作为属性。顶层表示模型(即视图模型)包含与页面或应用程序相关的属性,而表示模型(属性)包含与应用程序数据相关的属性。
We can take our design a step further and create a base view model class that can be used not only for PresentationOrders, but for any other class as well:
我们可以将我们的设计更进一步,创建一个基础视图模型类,它不仅可以用于 PresentationOrders,还可以用于任何其他类:
public class BaseViewModel
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
}
Now we can simplify our PresentationOrderVM like this:
现在我们可以像这样简化 PresentationOrderVM:
public class PresentationOrderVM : BaseViewModel
{
// Business properties
public PresentationOrder Order { get; set; }
}
public class PresentationOrderVM : BaseViewModel
{
// Business properties
public List<PresentationOrder> Orders { get; set; }
}
We can make our BaseViewModel even more re-usable by making it generic:
我们可以通过使 BaseViewModel 变得通用来使其更具可重用性:
public class BaseViewModel<T>
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business property
public T BusinessObject { get; set; }
}
Now our implementations are effortless:
现在我们的实现毫不费力:
public class PresentationOrderVM : BaseViewModel<PresentationOrder>
{
// done!
}
public class PresentationOrderVM : BaseViewModel<List<PresentationOrder>>
{
// done!
}
回答by fozylet
If you have properties specific to the view, and not related to the DB/Service/Data store, it is a good practice to use ViewModels. Say, you want to leave a checkbox selected based on a DB field (or two) but the DB field itself isn't a boolean. While it is possible to create these properties in the Model itself and keep it hidden from the binding to data, you may not want to clutter the Model depending on the amount of such fields and transactions.
如果您有特定于视图的属性,并且与 DB/Service/Data 存储无关,那么使用 ViewModel 是一个很好的做法。假设您想根据一个(或两个)数据库字段选中复选框,但数据库字段本身不是布尔值。虽然可以在模型本身中创建这些属性并将其隐藏在数据绑定之外,但您可能不希望根据此类字段和事务的数量来使模型混乱。
If there are too few view-specific data and/or transformations, you can use the Model itself
如果视图特定的数据和/或转换太少,您可以使用模型本身
回答by halfacreSal
I didn't read all the posts but every answer seems to be missing one concept that really helped me "get it"...
我没有阅读所有帖子,但每个答案似乎都缺少一个真正帮助我“理解”的概念......
If a Model is akin to a database Table, then a ViewModel is akin to a database View- A view typically either returns small amounts of data from one table, or, complex sets of data from multiple tables (joins).
如果 Model 类似于数据库Table,那么 ViewModel 类似于数据库View- 视图通常要么从一个表中返回少量数据,要么从多个表中返回复杂的数据集(联接)。
I find myself using ViewModels to pass info into a view/form, and then transfering that data into a valid Model when the form posts back to the controller - also very handy for storing Lists(IEnumerable).
我发现自己使用 ViewModels 将信息传递到视图/表单中,然后在表单回发到控制器时将该数据传输到有效模型中 - 对于存储列表(IEnumerable)也非常方便。
回答by Mayank
View model a is simple class which can contain more than one class property. We use it to inherit all the required properties, e.g. I have two classes Student and Subject
视图模型 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;}
}
Now we want to display records student's Name and Subject's Name in View (In MVC), but it's not possible to add more than one classes like:
现在我们想在 View (In MVC) 中显示学生姓名和科目姓名的记录,但不能添加多个类,例如:
@model ProjectName.Model.Student
@model ProjectName.Model.Subject
the code above will throw an error...
上面的代码会抛出一个错误...
Now we create one class and can give it any name, but this format "XyzViewModel" will make it easier to understand. It is inheritance concept. Now we create a third class with the following name:
现在我们创建一个类并且可以给它任何名称,但是这种格式“XyzViewModel”会更容易理解。这是继承的概念。现在我们使用以下名称创建第三个类:
public class StudentViewModel:Subject
{
public int ID {get; set;}
public string Name {get; set;}
}
Now we use this ViewModel in View
现在我们在 View 中使用这个 ViewModel
@model ProjectName.Model.StudentViewModel
@model ProjectName.Model.StudentViewModel
Now we are able to access all the properties of StudentViewModel and inherited class in View.
现在我们可以在 View 中访问 StudentViewModel 和继承类的所有属性。
回答by Jeroen
MVC doesn't have a viewmodel: it has a model, view and controller. A viewmodel is part of MVVM (Model-View-Viewmodel). MVVM is derived from the Presentation Model and is popularized in WPF. There should also be a model in MVVM, but most people miss the point of that pattern completely and they will only have a view and a viewmodel. The model in MVC is similar to the model in MVVM.
MVC 没有视图模型:它有模型、视图和控制器。视图模型是 MVVM(模型-视图-视图模型)的一部分。MVVM源自Presentation Model,在WPF中普及。MVVM 中也应该有一个模型,但是大多数人完全忽略了该模式的要点,他们只有一个视图和一个视图模型。MVC 中的模型类似于 MVVM 中的模型。
In MVC the process is split into 3 different responsibilities:
在 MVC 中,该过程分为 3 个不同的职责:
- View is responsible for presenting the data to the user
- A controller is responsible for the page flow
- A model is responsible for the business logic
- View负责将数据呈现给用户
- 控制器负责页面流
- 模型负责业务逻辑
MVC is not very suitable for web applications. It is a pattern introduced by Smalltalk for creating desktop applications. A web environment behaves completely different. It doesn't make much sense to copy a 40-year old concept from the desktop development and paste it into a web enviroment. However a lot of people think this is ok, because their application compiles and returns the correct values. That is, in my opinion, not enough to declare a certain design choice as ok.
MVC 不是很适合 Web 应用程序。它是 Smalltalk 为创建桌面应用程序引入的一种模式。Web 环境的行为完全不同。从桌面开发中复制一个已有 40 年历史的概念并将其粘贴到 Web 环境中并没有多大意义。然而,很多人认为这没问题,因为他们的应用程序编译并返回了正确的值。也就是说,在我看来,不足以将某个设计选择声明为可以。
An example of a model in a web application could be:
Web 应用程序中的模型示例可以是:
public class LoginModel
{
private readonly AuthenticationService authentication;
public LoginModel(AuthenticationService authentication)
{
this.authentication = authentication;
}
public bool Login()
{
return authentication.Login(Username, Password);
}
public string Username { get; set; }
public string Password { get; set; }
}
The controller can use it like this:
控制器可以这样使用它:
public class LoginController
{
[HttpPost]
public ActionResult Login(LoginModel model)
{
bool success = model.Login();
if (success)
{
return new RedirectResult("/dashboard");
}
else
{
TempData["message"] = "Invalid username and/or password";
return new RedirectResult("/login");
}
}
}
Your controller methods and your models will be small, easily testable and to the point.
您的控制器方法和模型将很小,易于测试且切中要害。
回答by Sheo Narayan
A lot of big examples, let me explain in clear and crispy way.
很多大例子,让我用清晰明了的方式来解释。
ViewModel = Model that is created to serve the view.
ViewModel = 为视图服务而创建的模型。
ASP.NET MVC view can't have more than one model so if we need to display properties from more than one models into the view, it is not possible. ViewModel serves this purpose.
ASP.NET MVC 视图不能有多个模型,所以如果我们需要将多个模型的属性显示到视图中,这是不可能的。ViewModel 用于此目的。
View Model is a model class that can hold only those properties that is required for a view. It can also contains properties from more than one entities (tables) of the database. As the name suggests, this model is created specific to the View requirements.
View Model 是一个模型类,它只能保存视图所需的那些属性。它还可以包含来自数据库的多个实体(表)的属性。顾名思义,此模型是针对 View 需求创建的。
Few examples of View Models are below
视图模型的几个例子如下
- To list data from more than entities in a view page – we can create a View model and have properties of all the entities for which we want to list data. Join those database entities and set View model properties and return to the View to show data of different entities in one tabular form
- View model may define only specific fields of a single entity that is required for the View.
- 要在视图页面中列出来自多个实体的数据——我们可以创建一个视图模型,并拥有我们要为其列出数据的所有实体的属性。加入这些数据库实体并设置 View 模型属性并返回到 View 以一种表格形式显示不同实体的数据
- 视图模型可以仅定义视图所需的单个实体的特定字段。
ViewModel can also be used to insert, update records into more than one entities however the main use of ViewModel is to display columns from multiple entities (model) into a single view.
ViewModel 也可用于将记录插入、更新到多个实体中,但 ViewModel 的主要用途是将来自多个实体(模型)的列显示到单个视图中。
The way of creating ViewModel is same as creating Model, the way of creating view for the Viewmodel is same as creating view for Model.
创建ViewModel的方式与创建Model的方式相同,为Viewmodel创建视图的方式与为Model创建视图的方式相同。
Here is a small example of List data using ViewModel.
这是一个使用 ViewModel的List 数据的小例子。
Hope this will be useful.
希望这将是有用的。
回答by gsivanov
ViewModel is workaround that patches the conceptual clumsiness of the MVC framework. It represents the 4th layer in the 3-layer Model-View-Controller architecture. when Model (domain model) is not appropriate, too big (bigger than 2-3 fields) for the View, we create smaller ViewModel to pass it to the View.
ViewModel 是解决 MVC 框架概念上笨拙问题的解决方法。它代表了 3 层模型-视图-控制器架构中的第 4 层。当 Model(域模型)不合适,对于 View 来说太大(大于 2-3 个字段)时,我们创建较小的 ViewModel 将其传递给 View。
回答by gsivanov
A view model is a conceptual model of data. Its use is to for example either get a subset or combine data from different tables.
视图模型是数据的概念模型。例如,它的用途是获取子集或组合来自不同表的数据。
You might only want specific properties, so this allows you to only load those and not additional unneccesary properties
您可能只需要特定的属性,因此这允许您只加载这些而不是其他不必要的属性

