zoukankan      html  css  js  c++  java
  • ASP.NET MVC: 修改ViewLocator来动态切换模板

     沈阳阿瑞 在我上一篇文章 ASP.NET MVC : 实现我们自己的视图引擎 中提到的一个问题:

    一直在思考这个问题,
    就是动态切换view来换主题
    [views]
    .|
    .---[Controler1]
    ...|
    ...---[blue]
    .... |
    .... ---index.aspx
    .... |
    .... ---Edit.aspx
    ...---[Red]
    .... |
    .... ---index.aspx
    .... |
    .... ---Edit.aspx
    .---[Controler2]
    ...|
    ...---[blue]
    .... |
    .... ---hello.aspx
    .... |
    .... ---report.aspx
    ...---[Red]
    .... |
    .... ---hello.aspx
    .... |
    .... ---report.aspx
    这样,主题view无法独立出来,不利于分离主题,管理主题。
    而我觉得,最理想的结构是
    [views]
    .|
    .---[blue]
    ...|
    ...---[Controler1]
    .... |
    .... ---index.aspx
    .... |
    .... ---Edit.aspx
    ...---[Controler2]
    .... |
    .... ---hello.aspx
    .... |
    .... ---report.aspx
    .---[Red]
    ...|
    ...---[Controler1]
    .... |
    .... ---index.aspx
    .... |
    .... ---Edit.aspx
    ...---[Controler2]
    .... |
    .... ---hello.aspx
    .... |
    .... ---report.aspx
    但是如果用这种,默认的模板路径是不支持的。
    看了你的文章恍然大悟。
    改一下ViewLocator的逻辑就可以了对吧。

    在这里简单给大家说下如何实现,只要给大家提供一点思路。其实把框架研究透彻了,真的很多问题都迎刃而解。

    大家如果有看过我的上篇文章 ASP.NET MVC : 实现我们自己的视图引擎 ,其实就明白的了。

    在这里,首先我们需要一个配置文件来配置站点要使用的模板(主题)。

    Config/Site.config :

    <?xml version="1.0" encoding="utf-8"?>
    <site>
    <appsetting ViewTheme="Default" />
    </site>

    然后修改默认的ViewLocator  :

    
    
    public class uLinkViewLocator : ViewLocator
        
    {
            
    public uLinkViewLocator()
            
    {
                
    base.ViewLocationFormats = new string[] { BaseviewPath + "/{1}/{0}.aspx",
                                                          BaseviewPath 
    + "/{1}/{0}.aspx",
                                                          BaseviewPath 
    + "/Shared/{0}.aspx",
                                                          BaseviewPath 
    + "/Shared/{0}.aspx",
                                                          
    "~/Views/{1}/{0}.aspx",
                                                          
    "~/Views/{1}/{0}.aspx",
                                                          
    "~/Views/Shared/{0}.aspx",
                                                          
    "~/Views/Shared/{0}.aspx"
                }
    ;

            }


            
    private string _baseviewPath;
            
    private string BaseviewPath
            
    {
                
    get
                
    {
                    
    if (string.IsNullOrEmpty(_baseviewPath))
                    
    {
                        
    string viewTheme = ConfigXml.Element("appsetting").Attribute("ViewTheme").Value;
                        viewTheme 
    = string.IsNullOrEmpty(viewTheme) ? "Default" : viewTheme;
                        _baseviewPath = "~/Views/" + viewTheme;
                    }

                    
    return _baseviewPath;
                }

            }


            
    private XElement configXml;
            
    private string path = System.Web.HttpRuntime.AppDomainAppPath + "/Config/Site.config";
            
    /// <summary>
            
    /// 加载XML文件
            
    /// </summary>

            private XElement ConfigXml
            
    {
                
    get
                
    {
                    
    if (configXml == null)
                    
    {
                        configXml 
    = XElement.Load(path);
                    }

                    
    return configXml;
                }

            }

        }
     

    还有修改ViewEngine的ViewLocator 为刚才创建的uLinkViewLocator :

    
    
    public class uLinkViewEngine : WebFormViewEngine
        
    {

            IViewLocator _viewLocator 
    = null;

            
    protected override void RenderView(ViewContext viewContext)
            
    {
                
    base.ViewLocator = this.ViewLocator;
                base.RenderView(viewContext);
            }


            
    public IViewLocator ViewLocator
            
    {
                
    get
                
    {
                    
    if (this._viewLocator == null)
                    
    {
                        
    this._viewLocator = new uLinkViewLocator();
                    }

                    
    return this._viewLocator;
                }

                
    set
                
    {
                    
    this._viewLocator = value;
                }

            }

        }
     

    然后创建一个ControllerFactory继承自默认的DefaultControllerFactory,以修改默认的controller中的ViewEngine为我们创建的uLinkViewEngine :

    
    
    public class uLinkControllerFactory : DefaultControllerFactory
        
    {
            
    protected override IController CreateController(RequestContext requestContext, string controllerName)
            
    {
                Controller controller 
    = (Controller)base.CreateController(requestContext, controllerName);
                controller.ViewEngine = new uLinkViewEngine();
    //修改默认的视图引擎为我们刚才创建的视图引擎
                return controller;
            }


        }

    在Global.asax.cs中的Application_Start 事件中注册我们的 uLinkControllerFactory :

    ControllerBuilder.Current.SetControllerFactory(typeof(uLinkControllerFactory));
    然后在写一个设置模板的Controller:
    ThemeController

     

    收工,搞定。
    详细就不说了,关键代码都高亮显示了。具体可以参考我上一篇文章ASP.NET MVC : 实现我们自己的视图引擎
    演示地址:http://www.aspdognet.cn/PEuLink/Home.mvc
     

    Enjoy!

    版权声明:本文首发于博客园,作者为QLeelulu
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

    作者:QLeelulu Follow QLeelulu on Twitter
    出处:http://QLeelulu.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利
  • 相关阅读:
    04_面向对象之多态
    03_面向对象之继承
    02_对象和对象封装
    01_什么是类
    01_函数对象
    python_IO操作之B模式介绍
    python_IO操作之rwa模式介绍
    python之初始IO操作01
    Flink基础(十七): Flink CEP 简介
    解决:UserBehavior is already defined as case class UserBehavior
  • 原文地址:https://www.cnblogs.com/QLeelulu/p/1248183.html
Copyright © 2011-2022 走看看