调试Razor从哪里开始
使用ASP.NET MVC时,我们知道,要使用Views中的视图,需要在Action中写
return View();
这个方法返回的返回值是一个 ViewResult,进入这个类,继承了父类ViewResultBase后只写了MasterName属性和FindView方法。
不过已经开始看到到ViewEngine的踪影了。
protected override ViewEngineResult FindView(ControllerContext context) { ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName); ...; }
跟进ViewEngineCollection.FindView去看看。
来到了ViewEngineCollection类,这是一个实现了Collection<IViewEngine>的类。
public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName) { if (controllerContext == null ) { throw new ArgumentNullException( "controllerContext" ); } if ( string .IsNullOrEmpty(viewName)) { throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName" ); } return Find(e => e.FindView(controllerContext, viewName, masterName, true ), e => e.FindView(controllerContext, viewName, masterName, false )); }
很简单的一个方法,跟进去
private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> cacheLocator, Func<IViewEngine, ViewEngineResult> locator) { // First, look up using the cacheLocator and do not track the searched paths in non-matching view engines // Then, look up using the normal locator and track the searched paths so that an error view engine can be returned return Find(cacheLocator, trackSearchedPaths: false ) ?? Find(locator, trackSearchedPaths: true ); } private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> lookup, bool trackSearchedPaths) { // Returns // 1st result // OR list of searched paths (if trackSearchedPaths == true) // OR null ViewEngineResult result; List< string > searched = null ; if (trackSearchedPaths) { searched = new List< string >(); } foreach (IViewEngine engine in CombinedItems) { if (engine != null ) { result = lookup(engine); if (result.View != null ) { return result; } if (trackSearchedPaths) { searched.AddRange(result.SearchedLocations); } } } if (trackSearchedPaths) { // Remove duplicate search paths since multiple view engines could have potentially looked at the same path return new ViewEngineResult(searched.Distinct().ToList()); } else { return null ; } }
乍一看,又是for又是if、else的有点不知所措,其实仔细一看结合上面的Find参数就能找到黄色加亮的几句代码关键代码。
是遍历了注册ViewEngine集合,调用ViewEngine各自的FindView,谁能找到View,就用谁。
那么遍历的ViewEngine集合怎么来的呢?要回到ViewResult的父类ViewResultBase中去看。
public ViewEngineCollection ViewEngineCollection { get { return _viewEngineCollection ?? ViewEngines.Engines; } set { _viewEngineCollection = value ; } }
如果没有定义那么就调用ViewEngines.Engines,这是一个很简单的静态类属性
public static class ViewEngines { private readonly static ViewEngineCollection _engines = new ViewEngineCollection { new WebFormViewEngine(), new RazorViewEngine(), }; public static ViewEngineCollection Engines { get { return _engines; } } }
回到刚才的遍历,由于RazorViewEngine的构造函数中定义了以下格式,在Views文件夹中也创建了相应的文件,所以选择了RazorViewEngine。
AreaViewLocationFormats = new [] { "~/Areas/{2}/Views/{1}/{0}.cshtml" , "~/Areas/{2}/Views/{1}/{0}.vbhtml" , "~/Areas/{2}/Views/Shared/{0}.cshtml" , "~/Areas/{2}/Views/Shared/{0}.vbhtml" };
好了,终于找到了Razor。
分类: ASP.NET MVC
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did48932