第4讲:MVC中的View层使用技巧(下讲)
2010.9.4 苏鹏
内容介绍
-HtmlHelper类
-ViewEngine引擎深入介绍
预备知识
-安装Visual Studio 2010 Express
-了解ASP.Net
-了解设计模式基本概念
Html.ActionLink和Html.RouteLine
-这两个控件都根据用户输入生成导航信息
-ActionLink根据生成调用另外Controller的链接
指定导航的Action
指定导航的Controller和Action
指定Action访问的参数
指定其它参数
RouteLink
Html.BeginForm
-这一标记完全模拟<form>标记
BeginForm标记与其他的HtmlHelper标记略有不同,其它的HtmlHelper标记是单个出现的,而BeginForm标记是成对出现的,它完整模仿了html当中使用的<form></form>。
第一种方式
第二种方式(推荐)
Html.Hidden
-用于生成隐藏文本
Html.DropDownList和Html.ListBox
-用于显示列表或选择值
-用于限制用户的输入
强类型支持
Html.PassWord
-Password的工作方式和textbox一样,只是提交以后数据会自动清空
(纠正:上图中的input控件的id属性的值应该是my_upwd)
Html.RadioButton
-生成一组选择值,并要求用户选择其一
Html.Partial和Html.RenderPartial
-用于输出局部html片段
它有四种重载
使用方式
注意:
RenderPartial由于是直接Response.Write输出,所以<%%>不需要冒号
Partial是转义之后的,需要编译一下,所以<%:%>有冒号
RenderPartial和Partial的本质上是一致的,不同之处是RenderPartial是直接输出Html的,Partial也是输出Html,但是它中间有个转义。RenderPartial在使用过程中,实际上是使用Response.Write方式直接往页面输出,它的性能在大型访问时会比Partial好很多,所以很多情况下我们会使用它来做相应的输出。
Html.Action和Html.RenderAction
-用于实现指定Controller的指定Action调用
在Controller里面有若干个函数,这些函数称为Action。它们的特点是,每一个Controller中的Action一般都返回ResultAction的结果。而ResultAction会作为View放到View层当中去,它们的关系大致是这样。但是有些情况下我们希望只输出或调用指定的Action,我们就使用Html.Action这种方法。我们刚刚介绍的Partial是把View当中的数据输出成独立文件,那么Action和RenderAction就是执行独立的Controller中的一个Action,并把结果返回出来。Action提供大量可扩展方法用于实现,因为每个ChildAction里面都可能会有一些Model数据,每个独立的Controller就可以被混合调用。
默认情况下,我们在返回的View中View一定是从某一个固定的Controller拿到的数据,很难在一个View中获得多个Controller的数据,因为Route不允许这么做。例如,Home文件夹下的View只能从HomeController中拿数据,如果想在HomeController和AccountController
中拿数据,这样就比较困难,而Html.Action就是专门为解决这个问题而来的。如果在Action上面声明一个Attribute的属性,叫ChildAction,那么在View调用的时候,就可以使用Html.Action把这个Action输出。
其他Controller的View调用MyController的Action
需要注意的是,一旦Action标记为ChildAction,它就不能被Url直接引用。还有一点,Controller里面有个Context控件上下文,它可以判定某个Action是不是ChildAction,如果是,这个Action就不能加其它标签,例如授权。如果一个Action是ChildAction,它就能在任意页面被引用,从而这种情况下不能再对它进行授权,这个逻辑也很容易理解。
另外一个是不能使用OutputCache进行设定,OutputCache一旦缓存之后,在不同页面调用这个ChildAction时系统就不知道该使用哪个实例了。
RenderAction
-传递参数
由于上面已经有一个Action名叫Menu并且是无参数的方法,所以下面的Menu重载不会被View识别
正确的方法是加一个ActionName标签
这样暴露给外面的Action名称就不在是Menu而是coolmenu,避免重载的同名问题
(纠正:这个调用的ActionName应该传入coolmenu而不是Menu,调用的方法应该是Html.RenderAction)
Html.TextArea
-用于生成<textarea>标签
它是用来传递文本的,不是RichTextBox,它本身不能做Html的显示,如果输出Html,它会对Html进行Encoder转义。
可以指定行和列输出
强类型支持
Html.ValidationMessage
-显示ModelState验证结果
它是类似于ViewState的东西,ViewState是在View层和Controller之间传数据的,ModelState是在View层和Model层之间传数据的。它是一个容器,用来存储一些数据结果。一般情况会把验证结果放在ModelState传到表示层。数据验证最好是放在Model层来做。
验证错误信息的class是field-validation-error,它定义在Content文件夹,里面有个style.css文件,把里面的样式修改了,错误信息的样式就可以改变了。
也可以直接指定错误信息,下面的例子是一旦ModelState的Name有值,就会显示“有些代码出错了”的错误信息
强类型支持
-显示一组报错数据
可以传入错误的主要说明参数
Html模板
-ASP.Net MVC2支持自定义模板
View引擎介绍
View引擎的作用主要是返回View,这个View是用户希望的任何格式,还能把这个View放到用户想放的任何地方。
在这里意思就是说,我们要生成一个aspx文件,这个aspx文件有各种HtmlHelper帮助显示html实例,还有各种其他方法集合生成的脚本。然后就把aspx解析生成html,这个就是WebForm引擎工作,它会调用各种aspx的API来生成html。
其实并不是所有引擎都会生成aspx页面,也并非,所有的View最终都生成html。还有一些引擎不接收View,而接收一些其他的东西,例如可以定制一些特别的DSL然后输出一些别的东西。
所以生成html并不是唯一的选择,接收Controller访问也并非唯一入口。
工作方式
配置ViewEngine
-对ViewEngine的配置写在Global.asax.cs
Application_Start函数是全局应用入口。在Application_Start中添加自己的引擎
实际上第一句Clear可以不写,因为MVC支持多引擎互相作用。
所以没必要清除之前的引擎。
使用View
-IViewEngine接口
FindView用迭代来找到每个ViewEngine的对象。当有一个View传过来时,ViewEngine的Collection对象通过不断询问每个Engine:“这个View的名字是你注册的么?”。如果是,那你就来解决这个问题,如果不是再给别人。所有都没有找到就返回null。
FindPartialView是专门找ChildAction用的。
FindView是给全局的View用的。
ReleaseView不必说了,Response就靠它了。
-IView接口
Render就是用来输出的方法。
ViewContext属性
-HttpContext(Request、Response、Server、Session等)
-Controller(返回ControllerBase实例 ,表明到底是谁调用ViewEngine)
-RouteData(返回Route对象,表明是从哪个区路由过来的)
-ViewData(字典包含所有从Controller过来的数据对象,Render很大程度上依赖于从这些对象取回的数据)
-TempData(也包含一些Controller过来的对象,但通常都是Cache过的对象)
-View
-ClientValidationEnable(判断客户端是否做数据验证,客户端不做就在Model层里做)
-FormContext(包含客户端Form的一些属性)
-FormIdGenerator(判断Form)
-IsChildAction(如果是true,就用PartialView来Render,如果是false,就用View来做)
-ParentActionViewContext
-Write(输出基本信息)
选择一个ViewEngine
-默认的WebFormViewEngine优势
-很像Webform
-使用masterpage
-支持使用C#或者vb.net写脚本
-使用System.Web.UI.Page
-VS2010自带智能感知
使用不同的ViewEngine
-渴望使用不同的语言(比如Ruby或者Python)
-希望得到更简单的Html用于支持更多浏览器(少用样式)
-希望输出结果并非Html,比如希望输出xaml,或者rss甚至是PDF
Spark
-支持使用动态语言生成Views比如IronPython和IronRuby
-简洁的输出
-支持一款类似MasterPage的技术
常见问题
-使用ViewEngine还是使用ActionResult
例如想输出Json对象,在MVC中刚好就有个JsonResult,假如没有,就只能用反射来寻找属性拼凑,这种情况写一个JsonResult就比较合适。反之,如果用xllt把xml输出成html,这种情况如果只写一个ActionResult不如写一个xllt的ViewEngine。
如果只有一种方法,就用ActionResult即可;如果有多种方法,就用ViewEngine。
2010.9.23