MVC 中的 ViewModel
此文章总结自:http://rachelappel.com/use-viewmodels-to-manage-data-amp-organize-code-in-asp.net-mvc-applications
ViewModel这个概念不只是在在MVC模式中有,你会在很多关于MVC、MVP、MVVM的文章中见到这个说法,并且这个概念在任何技术中都有可能提到,比如ASP.NET, Silverlight, WPF, or MVC... 现在我们来讨论如何在MVC中使用它。
ASP.NET MVC ViewModel 是什么?
在一般的情况下,我们向View中传递数据的时候,都是一个Model,当有一些额外的数据的时候,我们会使用viewbag等来进行,但是我们可以使用ViewModel将这些整合在一起也就是说:ASP.NET MVC 中的ViewModel允许你将一个或者多个data model和资源整合到一个对象中去,以此使View使用model的时候得到优化,下面的图说明了ViewModel的概念:

使用ViewModel的目的就是让View单个的对象来进行渲染,另一方面可以减少UI展示的逻辑代码,这个是很有必要的,也就是说View唯一的任务就是渲染单个的ViewModel对象,为了让concerns之间有一个清晰的分离,解耦意味着你的程序被设计的更好,所以我们要将对数据处理的代码放在它应该在的位置,远离View、controller。
在 MVC 中使用 ViewModel会让你的程序组件之间分离的更好,从而以与维护,记住,单元测试指的是测试小单元。下面列出的是你什么时候要使用ViewModel:
1、Incorporating dropdown lists of lookup data into a related entity
2、Master-detail records view Pagination:
3、combining actual data and paging information
4、Components like a shopping cart or user profile widget
5、Dashboards with multiple sources of disparate
6、data Reports, often with aggregate data
创建个ViewModel
尽管Viewmodel包含了几个实体,但是它任然只是一个类,没有什么特别的,放置它的位置可以是:
1、一个叫做ViewModels的文件夹中,这个文件夹可以放在项目的根目录中;
2、作为一个dll,我们从MVC项目中引用它;
3、放在一个分开的项目中的service layer;
而第一种方式无疑是最简单的一种,我们只需要创建一个文件夹,然后创建一个类就行了。
为了创建一个CustomerViewModel,我们要将Customer和StateDirctionary类型作为属性,来共同组建一个CustomerViewModel类,代码如下:
public class CustomerViewModel
{
public Customer Customer { get; set; }
public StatesDictionary States { get; set; } public CustomerViewModel(Customer customer)
{
Customer = customer;
States = new StatesDictionary();
}
}
将ViewModel发送到Veiw
当然我们是从Controller开始的,将ViewModel发送到View和我们将普通的model发送到View的做法是一样的,因为ViewModel只是一个类,View不知道也不会在意model或者viewModel是从哪里来的,你可以在controller中创建一个ViewModel的实例,为了保证controller的整洁,没有额外的代码,在Controller中需要做的只是取得model或者ViewModel的值,没有其他的:
public ActionResult Edit(int id)
{
Customer customer = context.Customers.Single(x => x.Id == id);
var customerViewModel = new CustomerViewModel(customer);
return View(customerViewModel);
}
然后就是view来渲染ViewModel
为了让View知道我们传过去的是哪一个对象,我们需要将@model关键字指向ViewModel,就像你在指定一个一般的model一样。
@model FourthCoffee.Web.ViewModels.CustomerViewModel
调用数据的代码:
<div class="editor-label"> @Html.LabelFor(model => model.Customer.FirstName)
</div><div class="editor-field">
@Html.EditorFor(model => model.Customer.FirstName) @Html.ValidationMessageFor(model => model.Customer.FirstName) </div>
@* ...View code continues rendering properties...
使用ViewModel的小建议:
1、因为使用ViewModel时需要手动的进行映射,但是当ViewModel很复杂的时候,这个将会变得比较困难,这个时候,我们就可以是使用AutoMapper来简化简化工作,AutoMapper会让你顺畅的在ViewModel和models之间创建映射,除此之外还有:POCO Generator、EF POCO Templates
2、只把你在View上用来渲染的属性放到ViewModel中
3、用View来指导ViewModel属性的创建,这样才能更好的渲染和维护
MVC 中的 ViewModel的更多相关文章
- MVC中使用viewmodel
新建一个类在类中写 public class DataViewmodel { public List<users> usersmodel { get; set; } public List ...
- 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
- Asp.Net MVC中使用ACE模板之Jqgrid
第一次看到ACE模板,有种感动,有种相见恨晚的感觉,于是迅速来研究.它本身是基于bootstrap和jqueryui,但更nice,整合之后为后台开发节省了大量时间. 发现虽然不是完美,整体效果还是不 ...
- Asp.net Mvc中利用ValidationAttribute实现xss过滤
在网站开发中,需要注意的一个问题就是防范XSS攻击,Asp.net mvc中已经自动为我们提供了这个功能.用户提交数据时时,在生成Action参数的过程中asp.net会对用户提交的数据进行验证,一旦 ...
- Knockout获取数组元素索引的2种方法,在MVC中实现
原文:Knockout获取数组元素索引的2种方法,在MVC中实现 在遍历数组.集合的时候,通常要获取元素的索引,本篇体验使用Knockout获取索引的2种方法. 假设有这样的一个模型: namespa ...
- 关于mvc中传入DataTable到视图的应用
MVC 中 如果是多表连接查询出的数据需要重新定义一个ViewModel,觉得很是麻烦,所以可以通过传一个DataTable到视图中可以避免这个问题 但是不知道会有什么不好的地方,有这方面经验的大神有 ...
- ASP.NET MVC 中 View 的设计
1. 前言 感觉有好长时间没有接触View 了,周末闲来无事,翻翻书桌上的书来回顾回顾ASP.NET MVC中View的相关内容. 2. View概述 View 通过应用程序在Action 中返回 ...
- 007.Adding a view to an ASP.NET Core MVC app -- 【在asp.net core mvc中添加视图】
Adding a view to an ASP.NET Core MVC app 在asp.net core mvc中添加视图 2017-3-4 7 分钟阅读时长 本文内容 1.Changing vi ...
- MVC中利用knockout.js实现动态uniqueId
题目比较拗口,但是这篇文章确实直说这一点. knockout.js是一个JS库,它的官网是http://knockoutjs.com/ 这篇文章的重点是knockout在工作的一个功能中的应用.最终效 ...
随机推荐
- BZOJ2310 : ParkII
单路径最大和问题,设f[i][j][S]表示到达(i,j),轮廓线状态为S的最优解. S用4进制m+1位数表示,0表示无插头,1表示左括号,2表示右括号,3表示独立插头. 在DP之前先进行一次预处理, ...
- 【原】storm源码之理解Storm中Worker、Executor、Task关系
Storm在集群上运行一个Topology时,主要通过以下3个实体来完成Topology的执行工作:1. Worker(进程)2. Executor(线程)3. Task 下图简要描述了这3者之间的关 ...
- android开发 BaseAdapter中getView()里的3个参数是什么意思
BaseAdapter适配器里有个getView()需要重写public View getView(int position,View converView,ViewGroup parent){ // ...
- js上传图片预览
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 给NSString增加Java风格的方法
给NSString增加Java风格的方法 文章目录 我实在受不了 NSString 冗长的方法调用了,每次写之前都要查文档.特别是那个去掉前后多余的空格的方法,长得离谱.与之对应的别的语言,拿 jav ...
- nodejs 更新最新版本
sudo npm cache clean -f sudo npm install -g n sudo n stable
- C#并行库(TaskParallelLibrary)用法小结
今天有空,总结一下.NET 4.5并行库(TaskParallelLibrary)用法. 也许C和C++的程序员刚刚开始写C#还习惯于new Thread来新建一个线程,但新建线程需要内存和CPU上下 ...
- sqlserver ldf过大处理方法
第一步 DUMP TRANSACTION databasename WITH NO_LOG -- 第二步:截断事务日志 BACKUP LOG databasename WITH ...
- 【转】Html页面结构范例
原文地址:http://www.51testing.com/html/38/225738-220986.html · HTML · HEAD · LINK ... CSS files required ...
- MongoDB数据备份与恢复
测试环境:windows 一. 导出数据F:\DbSoft\soft\master\bin>mongoexport /h 127.0.0.1 /port 50000 /d testdb /c t ...