技术开发 频道

asp.net mvc 皮肤的探索实现

  【IT168 技术文档】在利用ASP.NET MVC 框架编写程序时,有时我们需要根据业务自己  选择视图模板存放的位置,比如针对用户的设置选择不同的皮肤。如下:

  我们建一个  Themes/{Channel}/{Theme}/{Controller}/ {Action} 的存放路径,视图模板还用webform。 在Url客户端的显示上,我们还遵循{Channel}/{Controller}/ {Action}规则。

  实现思路是重写实现写一个ThemeViewEngine, 实现IViewEngine,作用是选择正确的WebForumView 的路径。

  看下实现代码: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Hosting;

namespace MvcApplicationTest.ThemeEngines
{
    
/// <summary>
    
/// 皮肤选择引擎
    
/// </summary>
    public class ThemeViewEngine:IViewEngine
    {
        
#region IViewEngine 成员

public ViewEngineResult FindView(ControllerContext controllerContext,
string viewName, string masterName, bool useCache)
{
return _FindView(controllerContext, viewName, null, useCache, "aspx");
}

public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            
return _FindView(controllerContext, partialViewName, null, useCache, "ascx");
        }


public void ReleaseView(ControllerContext controllerContext, IView view)
        {
            IDisposable disposable
= view as IDisposable;
            
if (disposable != null)
                disposable.Dispose();
        }

        
#endregion

private ViewEngineResult _FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache, string ext)
        {
            
if (controllerContext == null)
            
throw new ArgumentNullException("controllerContext is required.", "controllerContext");
            
if (string.IsNullOrEmpty(viewName))
            
throw new ArgumentException("viewName is required.", "viewName");


//当前不允许在Controller中指定View的masterName
            if (!string.IsNullOrEmpty(masterName))
            {
                
throw new ArgumentException("不允许在Controller中指定View的masterName", "masterName");
            }

            
string selectedThemeName = GetSelectedTheme(controllerContext);
            
string controllerName = controllerContext.RouteData.Values["controller"].ToString();
            
string viewPath = GetViewPath(controllerContext, selectedThemeName, controllerName, viewName, ext);
            
if (viewPath == null)
                
throw new InvalidOperationException(String.Format("The view '{0}' could not be located at these paths: {1}",
            viewName, GetChannelName(controllerContext)));

            
return new ViewEngineResult(new WebFormView(viewPath, null), this);
        }

        
#region Help Methods

        
/// <summary>
        
/// 获取皮肤文件路径
        
/// </summary>
        private static string GetViewPath(ControllerContext controllerContext,
        
string themeName, string controllerName, string viewName, string ext)
        {
            
return String.Format(@"~/Themes/{0}/{1}/{2}/{3}.{4}", GetChannelName(controllerContext), themeName, controllerName, viewName, ext);
        }

        
private static string GetChannelName(ControllerContext controllerContext)
        {
            
if (controllerContext.RouteData.Values["channel"] == null)
            {
                
return "";
            }
            
else
            {
                
return controllerContext.RouteData.Values["channel"].ToString();
            }
        }

        
/// <summary>
        
/// 获取需要显示的主题名称
        
/// </summary>
        private static string GetSelectedTheme(ControllerContext controllerContext)
        {
            
string themeName = "Default";
            
if (GetChannelName(controllerContext).ToLower() == "channel")
            {
                themeName
= "Default";
            }
            
return themeName;
        }

        
#endregion

    }
}

  在应用时,还需配置Global

routes.MapRoute(
              
"Channel",                                              // Route name
               "{channel}/{controller}/{action}/{id}",                 // URL with parameters
               new { channel="Channel", controller = "Home", action = "Index",
                      id
= "" }  // Parameter defaults
           );

            ViewEngines.Engines.Add(
new ThemeEngines.ThemeViewEngine());

 

0
相关文章