首页 优化推广 从零开始学习 ASP.NET MVC 1.0 (五) ViewEngine 深入解析与应用实例

从零开始学习 ASP.NET MVC 1.0 (五) ViewEngine 深入解析与应用实例

来源: | 时间:2010/8/9 14:42:28 |

一.摘要

本文讲解ViewEngine的作用, 并且深入解析了实现ViewEngine相关的所有接口和类, 最后演示了如何开发一个自定义的ViewEngine. 本系列文章已经全部更新为ASP.NET MVC 1.0版本.希望大家多多支持!

二.承上启下

首先注意: 我会将大家在MVC之前一直使用的ASP.NET页面编程模型称作ASP.NET WebForm编程模型.

上一讲中我们已经学习了如何向View传递Model, 以及如何在View中使用Model对象. 目前为止我们使用的都还是ASP.NET WebForm的页面模型,比如aspx页面,用户控件,母版页等. 最后这些页面中都要转换为HTML代码. 比如页面中的内嵌代码:

<% = ViewData["model"] %>

你是否思考过, 为何页面会支持<% %>这种语法? 为何最后一个aspx页面会在浏览器中以HTML代码的形式展现?

有人会回答这是ASP.NET自带的语法和功能. 没有错, ASP.NET帮我们做了编译页面, 输出HTML, 返回HTML给客户端浏览器等一系列工作.但是这些工作在MVC框架中有很多是属于View角色的职责. 为了继续使用原有的ASP.NET WebForm页面引擎, ASP.NET MVC抽象出来了ViewEngine这个角色. 顾名思义ViewEngine即视图引擎, 其主要作用就是找到View对象,  编译View对象中的语言代码(执行语言逻辑), 并且输出HTML. 下面讲解的WebFormViewEngine就是使用ASP.NET WebForm的页面编译/呈现功能实现的.

三.ViewEngine解析

下面将讲解和ViewEngine有关的各个接口和类.

IView接口

IView接口是对MVC结构中View对象的抽象, 此接口只有一个方法:

void Render(ViewContext viewContext, TextWriter writer);


Render方法的作用就是展示View对象, 通常是将页面HTML写入到Writer中供浏览器展示.

在本系列第三篇文章中我曾经分析过, 虽然IView对象是MVC中View角色的抽象, 并且提供了Render方法, 但是实际上真正的View角色的显示逻辑在ViewPage/ViewUserControl类中. 这是由于ASP.NET MVC提供的WebFormViewEngine视图引擎是使用原有的ASP.NET Web From的页面显示机制, 我们无法直接将WebForm模型中的页面转化为IView对象.

于是最后使用了一个折中的办法:

在IView对象的Render方法中调用WebForm页面的Render方法. WebFormView是目前ASP.NET MVC中唯一实现了IView接口的类

所以如果我们使用自定义的ViewEngine引擎, 就可以直接创建一个实现了IView接口的类实现Render方法.

 

IViewEngine接口

ViewEngine即视图引擎, 在ASP.NET MVC中将ViewEngine的作用抽象成了 IViewEngine 接口.

虽然IViewEngine的职责是寻找View对象, 但是其定义的两个方法:

  • FindPartialView
  • FindView

返回的结果是ViewEngineResult对象, 并不是View对象. 我们可以将ViewEngineResult理解为一次查询的结果, 在ViewEngineResult对象中包含有本次找到的IView对象.

ASP.NET MVC 提供了下面两个实现了IViewEngine接口的类:

  • VirtualPathProviderViewEngine
  • WebFormViewEngine

WebFormViewEngine是VirtualPathProviderViewEngine的派生类.

VirtualPathProviderViewEngine类实现了FindPartialView/FindView方法, 更够根据指定的路径格式搜索页面文件, 并且使用了提供了Cache机制缓存数据. 注意因为使用的是ASP.NET Cache,依赖HttpContext对象, 这就导致Cache无法在WebService或者WCf等项目中使用. VirtualPathProviderViewEngine寻找页面的方法依赖下面三个属性:

  • MasterLocationFormats
  • ViewLocationFormats
  • PartialViewLocationFormats

在VirtualPathProviderViewEngine中只定义了这三个属性, 具体的值在派生类WebFormViewEngine中指定:

        public WebFormViewEngine() {
            MasterLocationFormats = new[] {
                "~/Views/{1}/{0}.master",
                "~/Views/Shared/{0}.master"
            };

            ViewLocationFormats = new[] {
                "~/Views/{1}/{0}.aspx",
                "~/Views/{1}/{0}.ascx",
                "~/Views/Shared/{0}.aspx",
                "~/Views/Shared/{0}.ascx"
            };

            PartialViewLocationFormats = ViewLocationFormats;
        }

上面的代码中我们可以一步了然ViewEngine都搜索哪些路径.甚至还可以添加我们自己的路径和文件类型.

因为有了VirtualPathProviderViewEngine类, 在开发自定义的ViewEngine时不需要再编写搜索View文件的逻辑了.只需要定义搜索路径即可. 如果不使用ASP.NET WebForm的页面显示方式, 就需要自己定义的View对象如何显最后转化为HTML代码.

在后面的实例中会演示创建一个我们自定义的ViewEngine.

 

ViewEngineResult

ViewEngineResult是ViewEngine寻找View的查询结果.ViewEngineResult类没有派生类,  也就是说不同的ViewEngine返回的结果都是ViewEngineResult对象.

ViewEngineResult类有一个很重要的构造函数:

public ViewEngineResult(IView view, IViewEngine viewEngine)

 

以WebFormViewEngine为例, 在WebFormViewEngine类中定义了 MasterLocationFormats/ViewLocationFormats /PartialViewLocationFormats , 在调用FindPartialView/FindView方法时, 首先找到View对象的磁盘路径, 然后使用CreatePartialView/CreateView方法将磁盘路径转化实现了IView接口的WebFormView对象.

WebFormView中依然保存这页面对象的磁盘路径, 在调用Render时会根据磁盘路径创建ViewPage对象, 调用页面的Render方法.ASP.NET MVC编译页面时, 使用了.NET Framework 2.0以上的版本中提供的根据虚拟路径编译页面的函数:

BuildManager.CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType)

命名空间为System.Web.Compilation.

 

ViewEngineCollection

ViewEngineCollection是IViewEngine对象的集合类. 在我们的系统中可以使用多个ViewEngine,  在寻找时会返回第一个匹配的ViewEngineResult, 下面是ViewEngineCollection类的Find

服务热线

153 8323 9821

功能和特性

价格和优惠

网站和维护

推广和优化

微信服务号