体验AspNet MVC Preview5-更易扩展和使用的ViewEngine
作者:leven 日期:2008-08-30 13:38:49
Asp.Net Mvc终于等来了新版本,这次仍然是Preview版.该版本中加入了不少新特性.特别是在ViewEngine的管理上.得到了很大的改进,不仅让用户可以更方便的更换ViewEngine,而且还可以在一个系统中使用多个ViewEngine的可能得到了实现,本文将演示如何添加一个或者多个ViewEngine并让他们之间可以交互工作.
首先说明下P5对ViewEngine的改进,在老版本中,系统牵涉到ViewEngine管理的有两个接口,分别是: IViewEngine, IViewLocator,其中IVewEngine负责呈现View,IViewLocator负责对View的路径处理.同时,在Controller中对ViewEngine进行选择,让后在执行的时候将ViewEngine传递到ViewResult中,最后ViewResult使用ViewEngine来呈现ui.老版本的View部分大致类图如下:
它的执行流程大致如下:MVC框架根据Routing数据找到对应的Controller,而Controller中将根据IViewLocate来初始化一个ViewEngine(IViewLocater一般用来做路径选择)然后执行Controller的Execute方法,该方法间接通过ControllerActionInvoker来执行Action,每个Action都会返回一个ActionResult对象,然后,它执行ActionResult的ExecuteResult方法.系统有很多种ActionResult,当该ActionResult为ViewResult的时候,Controller会将自身的ViewEngine传递你这个ViewResult,在ViewResult中再最终使用ViewEngine来呈现数据.
但是在P5中,这个系统进行了较大的改进,增加了不少部分,使得扩展和管理更加方便了,当然,相应的,系统的复杂度也加大了.P5中关于ViewEngine的类图大致如下:
这个系统的执行流程大致如下:Mvc框架根据Routing中的数据找到相应的Controller(Controller实现了IController接口,且它不再管理ViewEngine),一个Controller包含一个IActionInvoker对象(将以前的ControllerActionInvoker接口化了),Controller中的Execute方法间接执行IActionInvoker的InvokeAction方法,系统默认的ActionInvoker将在该方法中间接执行Action,而每个Action会返回一个ActionResult,在P5中,系统自带了两种和ViewEngine有关的ActionResult,分别为: PartialViewResult和ViewResult,它们的继承关系可以见图,然后ViewResult会调用IViewEngine的FindPartialView或者FindView方法来获取对应的ViewEngineResult,最后调用ViewEngineResult中的IView的Render方法来呈现View.另外,系统中还有一个ViewEngines类来管理所有的ViewEngine,用户可以向ViewEngies中添加或者删除自己的ViewEngine.说到这儿可能有人觉得奇怪了,在这个执行流程中.没有任何地方说到ViewEngine的选择问题,如果系统有多个ViewEngine,系统怎么找到正确的ViewEngine并执行呢?其实,这只是系统将查找ViewEngine的工作交给了一个特殊的ViewEngine来完成,这就是CompositeViewEngine,它也就是ViewEngines.DefaultEngine这个特殊的ViewEngine中有一个ICollection
通过如此长的篇幅,我们分别了解了两个系统对ViewEngine的处理,那么接下来我们来实战一下,使用asp.net mvc p5来添加自己的ViewEngine并同时使用多个ViewEngine来呈现数据.
在这个例子中,工程和文件结构如下图:
在Library的程序集中,我们新增两个ViewEngine,分表是LViewEngine和WebViewEngine,并新增LView来具体呈现数据,供LViewEngine使用,而WebViewEngine使用系统自带的WebFormView来呈现数据.EngineManager用来管理ViewEngine.以实现系统换肤.BaseController继承自Controller,为web系统中所有Contoller的基类.
首先看LViewEngine类,该类代码如下:
它继承自系统的VirtualPathProviderViewEngine,由于VirtualPathProviderViewEngine中封装好了对View路径的处理,因此继承自它可以让我们免于对路径的处理.在构造方法中.我们对MasterLocationFormats, ViewLocationFormats, PartialViewLocationFormats进行了设定,它们分表表示Master的路径选择,View的路径选择和PartialView的路径选择.当更改path的时候系统会将选择view的目录进行更改,从而实现了换肤. CreatePartialView和CreateView分别用于返回该ViewEngine对应的View.在这儿,我们返回的是LView.
然后我们再看LView部分,代码如下:
这是一个非常简单的自定义View实现,它的功能是读取指定路径的txt文件,然后对其中的{$}标记进行替换,替换规则为,对ViewData中的数据根据Key和Value进行替换,比如{$test}将被替换为ViewData[“test”],对Model的数据进行属性替换,如,{$.test}将被替换为ViewData.Model.test.至于实现方法,不再细谈.
再看WebViewEngine,它相当是对系统自带的一个WebFormView的封装.本来WebFormViewEngine是查找Views下的文件.我们进行修改后也将支持换肤功能,根据不同的path参数来使用不同的view文件(在老版本中,要实现该功能必须定义自己的ViewLocater类,然后继承Controller,在Controller中替换本身的ViewLocater).
而在EngineManager中,提供了ChangeSkin方法,它可以方便的将系统的view路径更改.
下面我们来测试我们自带的LView,在web项目中,新建Global.asax,修改关键代码:
分别用来初始化Routing和设置初始skin.
然后新建ArticleController,加入一个index方法,代码如下:
然后新增skins/default/article/index.txt文件.文件内容如下:
测试实例图:
很好,LView已经工作正常了.
然后我们测试多个View的混合工作.
添加新的方法:
然后添加skins/default/article/mixer.aspx文件.代码如下:
这儿有两个Html.RenderPartial调用,分表呈现top和foot.从工程中可以看到.我们拥有skins/default/article/top.txt和skins/default/article/foot.ascx文件.按照我们的设想,在呈现top会使用LView,在呈现foot的时候会使用WebFormView.
Top.txt的代码如下:
Foot.ascx代码如下:
最后查看效果:
恭喜.多个viewengine都工作的很好.
到这儿,本篇文章的任务已经全部完成.最后提供文中的测试工程:
点击下载此文件
上一篇
下一篇
文章来自:
Tags: