2023-02-17 388
我是asp.net mvc的新手.我有一个问题,了解ViewModel的目的.
是什么是ViewModel,为什么我们需要一个用于ASP.NET MVC应用程序的ViewModel?
如果我有关于它的工作和解释的一个很好的例子,那将更好.
a
a view model表示您要在视图/页面上显示的数据,无论是用于静态文本还是可以添加到数据库中的静态文本或输入值(如文本框和下拉列表)(或编辑).它与你的
让我们说你有一个Employee class,它表示你的员工域模型,它包含以下属性(唯一标识符,名字,姓氏和日期创建):
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; }
}
您可以看到它只包含两个属性.这两个属性也在员工域模型中.为什么你可能会问? Id可能无法从视图中设置,它可能由employee表生成.还可以在存储过程中或应用程序的服务层中设置DateCreated.所以在视图模型中不需要Id和DateCreated.当您查看员工的详细信息时,您可能希望显示这两个属性(已被捕获的员工)作为静态文本.
加载视图/页面时,员工控制器中的”创建操作”方法将创建此视图模型的实例,如果需要,填充任何字段,然后将此视图模型传递给”视图”/”页面”:
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个属性的域模型,并且只想更新单个值.鉴于此方案,您只在视图模型中只有一个值/属性,而不是域对象中的所有属性.
视图模型不仅可以包含一个数据库表的数据.它可以将数据与另一个表组合.拍摄我的例子关于添加新的员工记录.除了添加的第一个和姓氏,您可能还想添加员工部门.此部门列表将来自您的Departments表.所以现在您可以在一个视图模型中具有来自Employees和Departments表的数据.然后,您将需要在视图模型中添加以下两个属性并使用数据填充它:
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
当查看第一次加载时,我会使用3.我将从数据库中获取员工的数据3.我会在我的视图/页面上显示静态文本,以便用户可以看到员工是什么被删除.当用户单击”删除”按钮时,我只需使用Id值3并将其传递给我的存储库图层.您只需要Id删除表中的记录.
另一个点,您真的需要每个动作的视图模型.如果是简单的数据,那么只需使用EmployeeViewModel即可.如果是复杂的视图/页面,它们彼此不同,那么我会建议您为每个用户使用单独的视图模型.
我希望这可以清除您对查看模型和域模型的任何混淆.
视图模型是表示特定视图中使用的数据模型的类.我们可以将此类用作登录页面的型号:
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; }
}
使用此视图模型,您可以定义视图(剃刀视图引擎):
@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);
}
生成此结果(在提交表单后拍摄的屏幕,验证消息):
您可以看到,视图模型具有许多角色:
视图模型的另一个例子及其检索:我们希望显示基本的用户数据,他的权限和用户名.我们创建一个特殊的视图模型,只包含必填字段.我们从数据库中检索来自不同实体的数据,但视图只意识到视图模型类:
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
}
编辑:我在我的博客上更新了这个答案:
我的答案有点冗长,但我认为将视图模型与其他类型的常用模型进行比较非常重要,以了解它们的不同以及为什么它们是必要的.
总结,并直接回答所要求的问题:
一般来说,视图模型是一个对象,其中包含呈现视图所需的所有属性和方法.查看模型属性通常与数据对象(如客户和订单)有关,另外,它们还包含与页面或应用程序本身相关的属性,例如用户名,应用程序名称等.查看模型提供了一个方便的对象来传递给渲染引擎创建HTML页面.使用视图模型的许多原因之一是查看模型提供了一种方法来测试某些演示任务,例如处理用户输入,验证数据,检索显示数据等.
这里是实体模型的比较(a.ka.dtos a.ka.模型),演示模型和视图模型.
数据传输对象a.k.a”model”
数据传输对象(DTO)是一个具有属性的类,它与数据库中的表架构匹配. DTO被命名为它们的常见用法,用于从数据存储和从数据存储中跳转数据.
DTOS的特征:
数据库表通常是归一化的,因此DTO通常也标准化.这使得它们用于呈现数据的限制.但是,对于某些简单的数据结构,它们通常会很好.
以下是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; }
}
演示模型
表示模型是一个实用程序类,用于在屏幕或报表上呈现数据.演示模型通常用于建模由来自多个DTO的数据组成的复杂数据结构.演示模型通常表示数据的非规范化视图.
演示模型的特性:
演示模型是”根据需要的”和”需要的”(而DTO通常与数据库模式相关).演示模型可用于为整个页面的数据,页面上的网格,或页面上的网格上的下拉列表.演示模型通常包含其他演示模型的属性.演示模型通常是为单一使用目的而构建的,例如在单个页面上渲染特定网格.
示例演示模型:
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); } }
}
查看模型
视图模型类似于呈现模型,其中是用于呈现视图的备份类.但是,它与演示模型或DTO有什么不同.视图模型通常包含与演示模型和DTO相同的属性,因此,它们通常为另一个而困惑.
视图模型的特征:
查看模型组成
如前所述,查看模型是复合对象,因为它们在单个对象上组合应用程序属性和业务数据属性.视图模型中使用的常用应用程序属性的示例是:
以下示例显示为什么查看模型的复合性质很重要,我们如何最好地构建高效可重复使用的视图模型.
假设我们正在编写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); } }
}
这个设计可能有效……但是如果我们想创建一个将显示订单列表的页面,那么怎么样?将重复PageTitle,用户名和ApplicationName属性,并变得笨重使用.此外,如果我们想在类的构造函数中定义某些页面级逻辑,何时何地?如果我们为每个将显示的每个订单创建实例,我们再也无法执行此操作.
组成在继承中
以下是我们可能重新定位订单呈现模型,使得它成为一个真实的视图模型,并且对显示单个呈现命令对象或呈现Order对象的集合有用:
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; }
}
查看上述两个类,我们可以看到一种思考视图模型的方法是它是一个包含另一个作为属性的演示模型的演示模型.顶级呈现模型(即查看模型)包含与页面或应用程序相关的属性,而演示模型(属性)包含与应用程序数据相关的属性.
我们可以更进一步地拍摄我们的设计,并创建一个基本视图模型类,该类不仅可以用于呈现,而且可以用于任何其他类:
public class BaseViewModel
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
}
现在我们可以简化我们的帖子,如下所示:
public class PresentationOrderVM : BaseViewModel
{
// Business properties
public PresentationOrder Order { get; set; }
}
public class PresentationOrderVM : BaseViewModel
{
// Business properties
public List<PresentationOrder> Orders { get; set; }
}
我们可以通过使IT通用使我们的底映射更加可用:
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; }
}
现在我们的实现毫不费力:
public class PresentationOrderVM : BaseViewModel<PresentationOrder>
{
// done!
}
public class PresentationOrderVM : BaseViewModel<List<PresentationOrder>>
{
// done!
}
以上所述是小编给大家介绍的什么是MVC中的ViewModel?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/34166.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态