Razor视图引擎学习

RazorView:

  RazorView和WebFormView都是继承自:BuildManageCompiledView。RazorView和WebFormView都有其各自对应的一个引擎:RazorViewEngine和WebFormViewEngine,今天咱们不讲WebFormView,主讲RazorView,我们来看看RazorView类型。在Razor引擎下,通过这一类型来表示View。

 1 public class RazorView : BuildManagerCompiledView

 2 {

 3     // Methods

 4     public RazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions);

 5     public RazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions, IViewPageActivator viewPageActivator);

 6     protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance);

 7 

 8     // Properties

 9     internal DisplayModeProvider DisplayModeProvider { get; set; }

10     public string LayoutPath { get; private set; }

11     public bool RunViewStartPages { get; private set; }

12     internal StartPageLookupDelegate StartPageLookup { get; set; }

13     public IEnumerable<string> ViewStartFileExtensions { get; private set; }

14     internal IVirtualPathFactory VirtualPathFactory { get; set; }

15 }

RenderView方法重写了基类BuildManagerCompiledView的方法。 属性LayoutPath表示布局文件的虚拟路径,而RunViewStartPages则表示是否运行ViewSatrt视图

,ViewStartFileExtensions属性则表示的是ViewStart文件的后缀。例如:“cshtml”、"vbhtml"。我们再来看看其内部的一个很重要的方法:RenderView.

 1   protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance)

 2     {

 3         if (writer == null)

 4         {

 5             throw new ArgumentNullException("writer");

 6         }

 7         WebViewPage page = instance as WebViewPage;

 8         if (page == null)

 9         {

10             throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.CshtmlView_WrongViewBase, new object[] { base.ViewPath }));

11         }

12         page.OverridenLayoutPath = this.LayoutPath;

13         page.VirtualPath = base.ViewPath;

14         page.ViewContext = viewContext;

15         page.ViewData = viewContext.ViewData;

16         page.InitHelpers();

17         if (this.VirtualPathFactory != null)

18         {

19             page.VirtualPathFactory = this.VirtualPathFactory;

20         }

21         if (this.DisplayModeProvider != null)

22         {

23             page.DisplayModeProvider = this.DisplayModeProvider;

24         }

25         WebPageRenderingBase startPage = null;

26         if (this.RunViewStartPages)

27         {

28             startPage = this.StartPageLookup(page, RazorViewEngine.ViewStartFileName, this.ViewStartFileExtensions);

29         }

30         HttpContextBase httpContext = viewContext.HttpContext;

31         WebPageRenderingBase base4 = null;

32         object model = null;

33         page.ExecutePageHierarchy(new WebPageContext(httpContext, base4, model), writer, startPage);

34     }

在此方法中,首先是将传过来的object对象转换为一个WebViewPage对象,接着设置WebViewPage对象的page的布局文件路径,视图文件路径,以及ViewContext和ViewData属性。接着执行初始化,对WebViewPage内部的一些属性进行设置,接着判断执行ViewStart页面的情况,得到表示开启页面的WebPageRenderingBase对象。最后执行page对象的ExecutePageHierarchy方法, 运行执行管道的页层次结构。

来瞧瞧其基类:BuilderManagerCompiledView

 1 public abstract class BuildManagerCompiledView : IView

 2 {

     // Methods11     internal BuildManagerCompiledView(ControllerContext controllerContext, string viewPath, IViewPageActivator viewPageActivator, IDependencyResolver dependencyResolver);

12     public void Render(ViewContext viewContext, TextWriter writer);

13     protected abstract void RenderView(ViewContext viewContext, TextWriter writer, object instance);

14 

15     // Properties

16     internal IBuildManager BuildManager { get; set; }

17     public string ViewPath { get; protected set; }

18 }

BuilderManagerCompiledView提供了一个RenderView的抽象方法供子类重写,上面我们已经讲过RenderView方法,可以参考。其中有一个Render方法,我们来看看:

 1 public void Render(ViewContext viewContext, TextWriter writer)

 2 {

 3     if (viewContext == null)

 4     {

 5         throw new ArgumentNullException("viewContext");

 6     }

 7     object instance = null;

 8     Type compiledType = this.BuildManager.GetCompiledType(this.ViewPath);

 9     if (compiledType != null)

10     {

11         instance = this.ViewPageActivator.Create(this._controllerContext, compiledType);

12     }

13     if (instance == null)

14     {

15         throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.CshtmlView_ViewCouldNotBeCreated, new object[] { this.ViewPath }));

16     }

17     this.RenderView(viewContext, writer, instance);

18 }

该方法中,首先是根据虚拟路径获得所在View的类型,然在根据类型和控制器上下文创建对象,这个方法最终还是调用了RenderView方法,将instance对象作为参数带入方法中.

可能你对BuildManagerCompiledView构造函数也感兴趣,特别是IViewPageActivator和IDependencyResolver。

1 internal BuildManagerCompiledView(ControllerContext controllerContext, string viewPath, IViewPageActivator viewPageActivator, IDependencyResolver dependencyResolver)

2 {

3     this._controllerContext = controllerContext;

4     this.ViewPath = viewPath;

5     this.ViewPageActivator = viewPageActivator ?? new BuildManagerViewEngine.DefaultViewPageActivator(dependencyResolver);

6 }

看到构造函数结尾对当前ViewPageActivator属性进行赋值的时候,给了一个默认值。看到了吧,当为null的时候,赋了一个DefaultViewPageActivator对象,此时构造函数中传入的参数是dependencyResolver对象。

 

Razor视图引擎:

 1 public class RazorViewEngine : BuildManagerViewEngine

 2 {

 3     // Fields

 4     internal static readonly string ViewStartFileName;

 5 

 6     // Methods

 7     static RazorViewEngine();

 8     public RazorViewEngine();

 9     public RazorViewEngine(IViewPageActivator viewPageActivator);

10     protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath);

11     protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath);

12 }

RazorViewEngine继承自BuildManagerViewEngine,内部通过控制器上下文,重写了基类的CreatePartialView创建分布视图方法和CreateView创建视图方法。构造函数设置了视图的搜寻顺序,如果没有提供,则按照这个顺序进行搜寻。

你可能感兴趣的:(学习)