• 调试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
  • 相关阅读:
    Linux 格式化扩展分区(Extended)
    linux编译警告 will be initialized after
    Flutter移动电商实战 --(36)FlutterToast插件使用
    Flutter移动电商实战 --(35)列表页_上拉加载更多制作
    Flutter移动电商实战 --(34)列表页_小BUG的修复
    Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果
    Flutter移动电商实战 --(32)列表页_小类高亮交互效果制作
    Flutter移动电商实战 --(31)列表页_列表切换交互制作
    Flutter移动电商实战 --(30)列表页_商品列表UI界面布局
    Flutter移动电商实战 --(29)列表页_商品列表数据模型建立
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2531729.html
Copyright © 2020-2023  润新知