• MVC ViewEngine视图引擎解读及autofac的IOC运用实践


    MVC 三大特色  Model、View、Control ,这次咱们讲视图引擎ViewEngine

    1.首先看看IViewEngine接口的定义

    namespace System.Web.Mvc
    {
        public interface IViewEngine
        {
            ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
            ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
            void ReleaseView(ControllerContext controllerContext, IView view);
        }
    }

    2.默认情况下,ASP.NET MVC提供2种视图引擎:WebFormViewEngine,RazorViewEngine

    namespace System.Web.Mvc
    {
        public static class ViewEngines
        {
            private static readonly ViewEngineCollection _engines = new ViewEngineCollection
            {
                new WebFormViewEngine(),
                new RazorViewEngine(),
            };
    
            public static ViewEngineCollection Engines
            {
                get { return _engines; }
            }
        }
    }

    这就是为什么ASP.NET MVC既支持*.aspx,又支持*.cshtml的原因了。

    那为什么所有的视图都要放在Views目录下呢,这个就要拜RazorViewngines所赐了。

    namespace System.Web.Mvc
    {
        public class RazorViewEngine : BuildManagerViewEngine
        {
            internal static readonly string ViewStartFileName = "_ViewStart";
    
            public RazorViewEngine()
                : this(null)
            {
            }
    
            public RazorViewEngine(IViewPageActivator viewPageActivator)
                : base(viewPageActivator)
            {
                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"
                };
                AreaMasterLocationFormats = 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"
                };
                AreaPartialViewLocationFormats = 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"
                };
    
                ViewLocationFormats = new[]
                {
                    "~/Views/{1}/{0}.cshtml",
                    "~/Views/{1}/{0}.vbhtml",
                    "~/Views/Shared/{0}.cshtml",
                    "~/Views/Shared/{0}.vbhtml"
                };
                MasterLocationFormats = new[]
                {
                    "~/Views/{1}/{0}.cshtml",
                    "~/Views/{1}/{0}.vbhtml",
                    "~/Views/Shared/{0}.cshtml",
                    "~/Views/Shared/{0}.vbhtml"
                };
                PartialViewLocationFormats = new[]
                {
                    "~/Views/{1}/{0}.cshtml",
                    "~/Views/{1}/{0}.vbhtml",
                    "~/Views/Shared/{0}.cshtml",
                    "~/Views/Shared/{0}.vbhtml"
                };
    
                FileExtensions = new[]
                {
                    "cshtml",
                    "vbhtml",
                };
            }
    
            protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
            {
                return new RazorView(controllerContext, partialPath,
                                     layoutPath: null, runViewStartPages: false, viewStartFileExtensions: FileExtensions, 
    viewPageActivator: ViewPageActivator) { DisplayModeProvider
    = DisplayModeProvider }; } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var view = new RazorView(controllerContext, viewPath, layoutPath: masterPath, runViewStartPages: true, viewStartFileExtensions: FileExtensions, viewPageActivator: V iewPageActivator) { DisplayModeProvider = DisplayModeProvider }; return view; } } }

    知道RazorViewEngine 内部定义,现在可以定制自己的需求啦

    public sealed class CustomViewEngine : RazorViewEngine  
        {  
      
            public CustomViewEngine()  
            {  
                ViewLocationFormats = new[]  
                {  
                    "~/Views/{1}/{0}.cshtml",  
                    "~/Views/Shared/{0}.cshtml",  
                    "~/CustomViewLocation/{1}/{0}.cshtml"  
                };  
            }  
            public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)  
            {  
                return base.FindView(controllerContext, viewName, masterName, useCache);  
            }  
        }  

    接下去就很简单了,只需要把原来的视图引擎清空,加载自己的视图引擎就可以了。

    protected void Application_Start()  
    {  
        AreaRegistration.RegisterAllAreas();  
      
        ViewEngines.Engines.Clear();  
      
        ViewEngines.Engines.Add(new CustomViewEngine());  
      
        RegisterGlobalFilters(GlobalFilters.Filters);  
        RegisterRoutes(RouteTable.Routes);  
    }  

    这样可以改变展示页面必须在View下的显示的局面,从而更加的灵活,为视图从Views拿出去 提供了必要条件,还需要一些其他操作:

          这个时候很明显,已经开始在我们自定义加的视图文件夹下面开始找视图了.但是找到了,却提示这个视图文件没派生自 WebViewPage 或 WebViewPage<TModel>

    我们知道Razor视图最终都会编译成一个类,这个类会自动继承WebViewPage 或 WebViewPage<TModel>,(这个是强类型视图了..)(大家可以用反编译工具看见)

    但是我们把视图从Views下面拿出来了, MVC框架就不会编译的时候让他继承WebViewPage 或 WebViewPage<TModel>

         解决方案:

         第一种:这种最简单.把Views下面的web.config文件复制一个到MyCustomView下面,这样错误就没有了!就可以正常访问找到视图了

    原理就是

    上图中Views文件夹下面的Web.config中有一个节点配置了这么一句话<pages pageBaseType="System.Web.Mvc.WebViewPage"> .很明显是继承WebViewPage 的意思

    有这个,此文件夹里面所有的视图编译的时候会自动运行这个,肯定就继承了WebViewPage

    视图文件多的时候很适合这样做哦

    我们知道ASP.NET框架对Web.config是 有就近原则和继承原则的,也就是你在网站根目录的Web.config下面的配置,适用于网站下面所有的程序,当你在子文件下面再有Web.config 的时候,他会就近选择使用(如果配置局部,想不使用全局配置,就可以自己加一个配置文件哦,是不是有点类似CSS中的就近原则,哈哈)

    第二种:直接在视图中加一句指令

    @inherits System.Web.Mvc.WebViewPage

    作用不言而喻,当前视图会继承WebViewPage ,但多个视图的时候每个里面都写一句这个烦不烦!!所以不推挤这个啦!

    参考链接:http://www.cnblogs.com/chengxiaohui/articles/4837193.html

                  http://blog.csdn.net/jackvs/article/details/7788743

  • 相关阅读:
    [Codeforces809D] Hitchhiking in the Baltic States
    [Codeforces1148H] Holy Diver
    [PKUWC2018]猎人杀
    [Codeforces566C] Logistical Questions
    越野赛车问题
    Suffix Array
    第05组(65) 需求分析报告
    第05组(65) 团队展示
    第三次作业
    结对编程作业
  • 原文地址:https://www.cnblogs.com/meiCode/p/MVC.html
Copyright © 2020-2023  润新知