我是ASP的新手。净MVC。我在理解ViewModel的目的方面有一个问题。
什么是ViewModel,为什么我们需要一个ASP的ViewModel。NET MVC应用程序?
如果我能给出一个关于它的工作和解释的好例子,那就更好了。
我是ASP的新手。净MVC。我在理解ViewModel的目的方面有一个问题。
什么是ViewModel,为什么我们需要一个ASP的ViewModel。NET MVC应用程序?
如果我能给出一个关于它的工作和解释的好例子,那就更好了。
当前回答
视图模型是一个类,我们可以使用它在视图上呈现数据。假设您有两个实体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。
其他回答
很多大的例子,让我用一种清晰明了的方式解释。
ViewModel =为视图创建的模型。
ASP。NET MVC视图不能有多个模型,所以如果我们需要在视图中显示来自多个模型的属性,这是不可能的。ViewModel就是这个目的。
视图模型是一个模型类,它只能保存视图所需的那些属性。它还可以包含来自数据库的多个实体(表)的属性。顾名思义,这个模型是专门为View需求创建的。
下面是一些视图模型的例子
要在视图页中列出来自多个实体的数据,可以创建一个 查看模型,并拥有我们想要的所有实体的属性 列出数据。连接这些数据库实体并设置View模型 属性,并返回到视图以显示不同的数据 一个表格形式的实体 视图模型可能只定义单个实体的特定字段 视图所需。
ViewModel还可以用于将记录插入和更新到多个实体中,但ViewModel的主要用途是将多个实体(模型)中的列显示到单个视图中。
创建ViewModel的方法与创建Model的方法相同,为ViewModel创建视图的方法与为Model创建视图的方法相同。
下面是一个使用ViewModel的列表数据的小示例。
希望这对你有用。
If you want to study code on how to set up a "Baseline" web application with ViewModels I can advise you to download this code on GitHub: https://github.com/ajsaulsberry/BlipAjax. I developed large enterprise applications. When you do this it's problematic to set up a good architecture that handles all this "ViewModel" functionality. I think with BlipAjax you will have a very good "baseline" to start with. It's just a simple website, but great in its simplicity. I like the way they used the English language to point out what's really needed in the application.
ViewModel是包含在MVC视图中使用的字段的模型。对视图使用ViewModel有以下好处:
由于数据库模型(实体类)包含单个表的数据。如果需要来自多个表的数据,一个ViewModel可以有多个表的字段。 用户不能直接与数据库模型交互,因此数据库层或模型是安全的。 它用于通过存储库从数据库模型获取数据并将其传递给视图。类似地,它利用向数据库模型发布数据来更新数据库记录。
视图模型表示希望在视图/页面上显示的数据,无论是用于静态文本还是用于可以添加到数据库(或编辑)的输入值(如文本框和下拉列表)。它与您的领域模型有所不同。它是视图的模型。
假设你有一个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; }
}
视图模型与域模型的不同之处在于,视图模型只包含您希望在视图上使用的数据(由属性表示)。例如,假设你想添加一个新的员工记录,你的视图模型可能是这样的:
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? Id might not be set from the view, it might be auto generated by the Employee table. And DateCreated might also be set in the stored procedure or in the service layer of your application. So Id and DateCreated are 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.
当加载视图/页面时,员工控制器中的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
}
}
您的视图/页面可能看起来像这样(假设您正在使用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>
因此,验证将只在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");
}
}
使用数据注释,它可能是这样的:
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; }
}
要记住的关键是,视图模型只表示您想要使用的数据,而不是其他数据。如果您有一个具有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 Departments table. So now you have data from the Employees and Departments tables in one view model. You will just then need to add the following two properties to your view model and populate it with data:
public int DepartmentId { get; set; }
public IEnumerable<Department> Departments { get; set; }
在编辑员工数据(已经添加到数据库的员工)时,它与上面的示例没有太大区别。创建一个视图模型,例如将其命名为EditEmployeeViewModel。在这个视图模型中只有您想要编辑的数据,比如姓和名。编辑数据并单击提交按钮。我不会太担心Id字段,因为Id值可能会在URL中,例如:
http://www.yourwebsite.com/Employee/Edit/3
使用这个Id并将其与您的姓和名值一起传递到存储库层。
当删除一条记录时,我通常遵循与编辑视图模型相同的路径。我也会有一个URL,例如:
http://www.yourwebsite.com/Employee/Delete/3
当视图第一次加载时,我将使用Id 3从数据库中获取员工的数据。然后,我将只在视图/页面上显示静态文本,以便用户可以看到正在删除的员工。当用户单击Delete按钮时,我将只使用Id值3并将其传递给我的存储库层。只需要Id就可以从表中删除一条记录。
另一点,你并不真的需要每个操作的视图模型。如果它是简单的数据,那么只使用EmployeeViewModel就可以了。如果是复杂的视图/页面,并且它们彼此不同,那么我建议您为每个视图使用单独的视图模型。
我希望这能消除您对视图模型和域模型的任何困惑。
ViewModel包含在视图中表示的字段(用于 LabelFor、EditorFor DisplayFor助手) ViewModel可以使用数据注释拥有特定的验证规则 或IDataErrorInfo。 ViewModel可以有来自不同数据的多个实体或对象 模型或数据源。
设计视图模型
public class UserLoginViewModel
{
[Required(ErrorMessage = "Please enter your username")]
[Display(Name = "User Name")]
[MaxLength(50)]
public string UserName { get; set; }
[Required(ErrorMessage = "Please enter your password")]
[Display(Name = "Password")]
[MaxLength(50)]
public string Password { get; set; }
}
在视图中显示视图模型
@model MyModels.UserLoginViewModel
@{
ViewBag.Title = "User Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<div class="editor-label">
@Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</div>
<p>
<input type="submit" value="Log In" />
</p>
}
行动起来
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(UserLoginViewModel user)
{
// To access data using LINQ
DataClassesDataContext mobjentity = new DataClassesDataContext();
if (ModelState.IsValid)
{
try
{
var q = mobjentity.tblUsers.Where(m => m.UserName == user.UserName && m.Password == user.Password).ToList();
if (q.Count > 0)
{
return RedirectToAction("MyAccount");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
catch (Exception ex)
{
}
}
return View(user);
}
在ViewModel中只放置那些你想要显示的字段/数据 视图/页。 由于view表示ViewModel的属性,因此它是 易于渲染和维护。 当ViewModel变得更加复杂时,使用mapper。