基于Web Form引擎的WebFormViewEngine和针对Razor引擎的RazorViewEngine都是抽象类型BuildManagerViewEngine的子类,而后者又继承自VirtualPathProviderViewEngine。在这里我们仅仅对实现在RazorViewEngine中View获取的逻辑进行简单介绍。由于Razor引擎下的View通过RazorView对象来表示,而RazorView通过View文件的虚拟路径来构建,所以RazorViewEngine的View获取机制在于根据当前上下文找到与指定View名称相匹配的View文件(.cshtml或者.vbhtml文件),然后根据该 View文件的虚拟路径创建一个RazorView对象并最终封装成ViewEngineResult对象返回。
实现在RazorViewEngine中的目标View文件的搜索是根据一个预定义顺序进行的。如果当前请求不是针对某个Area的,下面的列表代表了View的搜索顺序:
~/Views/{ControllerName}/{ViewName}.cshtml
~/Views/{ControllerName}/{ViewName}.vbhtml
~/Views/Shared/{ViewName}.cshtml
~/Views/Shared/{ViewName}.vbhtml
对于针对某个Area的请求,RazorViewEngine会先按照如下的顺序对目标View进行搜索。如果在这个列表中没有成功找到目标View文件,会继续按照上面的属性进行搜索。
~/Areas/{AreaName}/Views/{ControllerName}/{ViewName}.cshtml
~/Areas/{AreaName}/Views/{ControllerName}/{ViewName}.vbhtml
~/Areas/{AreaName}/Views/ Shared /{ViewName}.cshtml
~/Areas/{AreaName}/Views/ Shared /{ViewName}.vbhtml
如果按照上面的搜索顺序依然找不目标View文件,RazorViewEngine会根据这个列表创建并返回一个ViewEngineResult对象。这里介绍的View搜索机制不仅仅应用于普通的View文件,还应用于Partial View和布局文件的搜索。
ViewEngine不仅仅通过FindView/FindPartialView根据当前上下文获取指定的View,还通过ReleaseView对指定的View进行释放回收操作。ReleaseView方法在RazorViewEngine的实现很简单,如果指定的View对象的类型实现IDispose接口,它会直接调用其Dispose方法。下图所示的UML体现了Razor引擎涉及的相关类型/接口以及它们之间的相互关系。
在《ASP.NET MVC的Razor引擎:RazorView》一文中我们创建了一个用于模拟RazorView的SimpleRazorView,现在我们为它创建一个对应的RazorViewEngine,我们直接在该实例项目中添加如下一个SimpleRazorViewEngine。
1: public class SimpleRazorViewEngine: IViewEngine 2: { 3: private string[] viewLocationFormats = new string[] { 4: "~/Views/{1}/{0}.cshtml", 5: "~/Views/{1}/{0}.vbhtml", 6: "~/Views/Shared/{0}.cshtml", 7: "~/Views/Shared/{0}.vbhtml" }; 8: private string[] areaViewLocationFormats = new string[] { 9: "~/Areas/{2}/Views/{1}/{0}.cshtml", 10: "~/Areas/{2}/Views/{1}/{0}.vbhtml", 11: "~/Areas/{2}/Views/Shared/{0}.cshtml", 12: "~/Areas/{2}/Views/Shared/{0}.vbhtml" }; 13: 14: public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) 15: { 16: return FindView(controllerContext, partialViewName, null, useCache); 17: } 18: 19: public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) 20: { 21: string controllerName = controllerContext.RouteData.GetRequiredString("controller"); 22: object areaName; 23: List<string> viewLocations = new List<string>(); 24: Array.ForEach(viewLocationFormats, format => viewLocations.Add(string.Format(format, viewName, controllerName))); 25: if (controllerContext.RouteData.Values.TryGetValue("area", out areaName)) 26: { 27: Array.ForEach(areaViewLocationFormats, format=>viewLocations.Add(string.Format(format,viewName,controllerName, areaName))); 28: } 29: foreach (string viewLocation in viewLocations) 30: { 31: string filePath = controllerContext.HttpContext.Request.MapPath(viewLocation); 32: if (File.Exists(filePath)) 33: { 34: return new ViewEngineResult(new SimpleRazorView(viewLocation), 35: this); 36: } 37: } 38: return new ViewEngineResult(viewLocations); 39: } 40: 41: public void ReleaseView(ControllerContext controllerContext, IView view) 42: { 43: IDisposable disposable = view as IDisposable; 44: if (null != disposable) 45: { 46: disposable.Dispose(); 47: } 48: } 49: }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索string
, 文件
, view
, cshtml
, indexqtqlist view
, AREAS
, RazorViewEngine
, view文件夹
当前view
,以便于您获取更多的相关知识。