zoukankan      html  css  js  c++  java
  • Asp.Net MVC:基于cookie的用户自选视图引擎实现

    作者:
    leven
    日期:
    2008-11-27 17:38:47

    在我以前的文章中详细介绍了目前mvc框架中的视图引擎管理,这个视图引擎可以方便的实现系统多视图引擎的管理,让系统可以轻松更好视图引擎,但是,在一些应用,比如bbs,多用户blog中,往往需要提供用户自选skin的功能,比如bbs中某个用户通过菜单可以随意更换自己的skin设置,而mvc框架的默认视图管理器对这个要求就无法做到了,而本文则是使用viewengine规则来实现一个用户自选视图引擎的功能.

    在本系统中,用户选择的skin信息将保存在cookie中,这意味着可以让用户控制这个选择保存的时间.

    首先,这个系统仍然是基于ViewEngine,我们在以前的文章中可以看到,mvc框架用一个AutoViewEngine来管理存在的所有ViewEngine,那么我们也可以考虑用一个SelectViewEngine来管理一系列我们特定的可选择ViewEngine.下面先看看这个核心部分的类:


     

    从图中可以看到,这儿我们提供了一个新的接口ISelectViewEngine,它在普通的ViewEngine上添加了一个新的Name属性,该属性标示着唯一的视图引擎名称,然后我们对WebFormViewEngine进行封装,并实现ISelectViewEngine接口:


            public SelectWebFormViewEngine(string name) {
                Name 
    = name;
                MasterLocationFormats 
    = new[] {
                    
    "~/skins/" + Name + "/{1}/{0}.master",
                    
    "~/skins/" + Name + "/shared/{0}.master"
                }
    ;
                ViewLocationFormats 
    = new[] {
                    
    "~/skins/" + Name + "/{1}/{0}.aspx",
                    
    "~/skins/" + Name + "/{1}/{0}.ascx",
                    
    "~/skins/" + Name + "/shared/{0}.aspx",
                    
    "~/skins/" + Name + "/shared/{0}.ascx"
                }
    ;
                PartialViewLocationFormats 
    = ViewLocationFormats;
            }

     

    从上面的代码可以看到,默认的不同skin分别放在~/skins目录下,不同的SelectWebFormViewEngine对应不同的子目录.

    然后我们实现一个基本的SelectViewEngine来管理所有的可选择ViewEngine,关键代码如下:

     


            /// <summary>
            
    /// 可选择视图引擎容器,通过Add来增加系统中可用的视图引擎
             
    /// </summary>
            public IDictionary<string, ISelectViewEngine> Engines {
                
    get { return _engines; }
            }

            
    /// <summary>
            
    /// 通过Cookie来选择用户所选择的ViewEngine
            
    /// </summary>
            
    /// <param name="context"></param>
            
    /// <returns></returns>
            private IViewEngine Find(ControllerContext context) {
                
    string skin = context.HttpContext.GetSelectSkinName();
                
    if (!_engines.ContainsKey(skin)) {
                    
    throw new Exception(String.Format("模板{0}未找到.", skin));
                }
                
    return _engines[skin];
            }

            
    #region IViewEngine Members

            
    /// <summary>
            
    /// 调用通过Find方法找到的ViewEngine的FindPartialView方法
            
    /// </summary>
            
    /// <param name="controllerContext"></param>
            
    /// <param name="partialViewName"></param>
            
    /// <returns></returns>
            public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName) {
                
    return Find(controllerContext).FindPartialView(controllerContext, partialViewName);
            }

            
    /// <summary>
            
    /// 调用通过Find方法找到的ViewEngine的FindView方法
            
    /// </summary>
            
    /// <param name="controllerContext"></param>
            
    /// <param name="viewName"></param>
            
    /// <param name="masterName"></param>
            
    /// <returns></returns>
            public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName) {
                
    return Find(controllerContext).FindView(controllerContext, viewName, masterName);
            }


     

    那么我们如何确定用户选择了哪个ViewEngine呢?在本例中是采用了cookie的方式,在ViewEngineExtension中,我们封装了几个扩展方法用来获取cookie和设置cookie:

     


        public static class ViewEngineExtension {
            
    private static readonly string _cookiename = "select_skin_name";
            
    private static readonly string _defaultskin = "default";

            
    public static string GetSelectSkinName(this HttpContextBase context) {
                HttpCookie cookie 
    = context.Request.Cookies[_cookiename];
                
    if (cookie != null{
                    
    return cookie.Value;
                }

                
    return _defaultskin;
            }


            
    public static void SelectSkin(this HttpContextBase context, ISelectViewEngine select) {
                HttpCookie cookie 
    = new HttpCookie(_cookiename);
                cookie.Value 
    = select.Name;
                
    if (context.Response.Cookies.AllKeys.Contains(_cookiename))
                    context.Response.Cookies.Remove(_cookiename);
                context.Response.Cookies.Add(cookie);
            }


            
    public static void SelectSkin(this HttpContextBase context, string name) {
                HttpCookie cookie 
    = new HttpCookie(_cookiename);
                cookie.Value 
    = name;
                
    if (context.Response.Cookies.AllKeys.Contains(_cookiename))
                    context.Response.Cookies.Remove(_cookiename);
                context.Response.Cookies.Add(cookie);
            }


            
    public static void ResetSkin(this HttpContextBase context) {
                HttpCookie cookie 
    = new HttpCookie(_cookiename);
                cookie.Value 
    = _defaultskin;
                
    if (context.Response.Cookies.AllKeys.Contains(_cookiename))
                    context.Response.Cookies.Remove(_cookiename);
                context.Response.Cookies.Add(cookie);
            }

        }

     

    总结下VIewEngine的工作流程:

    Controller -> ViewEngines.Default.FindView -> SelectViewEngine.FindView -> SelectWebFormViewEngine.FindView

    也就是说,系统调用FindView或者FindPartialView方法最终还是会调用到我们在系统中已经注册过的ISelectViewEngine的FindView或者FindPartialView方法.最后展示下如何注册这些SelectViewEngine:

     


            protected void Application_Start(object sender, EventArgs e) {
            
    //注册路由
                 InitRouting(RouteTable.Routes); 
                ViewEngines.Engines.Clear();
                SelectViewEngine engine 
    = new SelectViewEngine();
                SelectWebFormViewEngine defaultEngine 
    = new SelectWebFormViewEngine();
                engine.Engines.Add(defaultEngine.Name, defaultEngine);
                SelectWebFormViewEngine selectEngine 
    = new SelectWebFormViewEngine("select");
                engine.Engines.Add(selectEngine.Name, selectEngine);
                ViewEngines.Engines.Add(engine); 
            }

  • 相关阅读:
    【转载】分布式环境Raft一致性共识算法解读
    从码农到工程师:只要做到这6点
    产品思维的修炼–技术的必修课
    工具篇
    安全测试
    测试体会
    测试题目
    软件测试工具
    常见的性能测试方法
    性能测试在软件测试的周期位置
  • 原文地址:https://www.cnblogs.com/luluping/p/1387967.html
Copyright © 2011-2022 走看看