控制器分组:Area

思路

 1     需要添加 AreaRouteHeler,便于创建控制器分组信息。

 2    添加自定义视图引擎,为了控制器能够导航到各Area中的页面。

 

步骤:

 1 .    添加 AreaRouteHeler。

  

  1. /// <summary>  
  2.    /// 控件器分组帮助类  
  3.    /// </summary>  
  4.    public class AreaRouteHeler  
  5.    {  
  6.        /// <summary>  
  7.        /// 创建控制器域  
  8.        /// </summary>  
  9.        /// <param name="routeCollection">路由集合</param>  
  10.        /// <param name="areaName">控制器域</param>  
  11.        /// <param name="controllerNameSpace">控制器NameSpace</param>  
  12.        /// <param name="routeEntries">路由参数(可多个)</param>  
  13.        public static void CreateArea(this RouteCollection routeCollection, string areaName, string controllerNameSpace, params Route[] routeEntries)  
  14.        {  
  15.            if (routeEntries == null || routeEntries.Length <= 0)  
  16.            {  
  17.                return;  
  18.            }  
  19.            foreach (Route route in routeEntries)  
  20.            {  
  21.                if (route.Constraints == null)  
  22.                {  
  23.                    route.Constraints = new RouteValueDictionary();  
  24.                }  
  25.                if (route.Defaults == null)  
  26.                {  
  27.                    route.Defaults = new RouteValueDictionary();  
  28.                }  
  29.                if (route.DataTokens == null)  
  30.                {  
  31.                    route.DataTokens = new RouteValueDictionary();  
  32.                }  
  33.                route.Constraints.Add("area", areaName);  
  34.                route.DataTokens.Add("namespaces", new[] { controllerNameSpace });  
  35.                route.Defaults.Add("area", areaName);  
  36.                //To support "new Route()" in addition to "routes.MapRoute()"  
  37.                if (!routeCollection.Contains(route))  
  38.                {  
  39.                    routeCollection.Add(route);  
  40.                }  
  41.            }  
  42.        }  
  43.    }  

  

  1. 2.   添加自定义视图引擎.

    

  1. /// <summary>  
  2.    /// 控件器分组视图引擎  
  3.    /// </summary>  
  4.    public class AreaViewEngine : WebFormViewEngine  
  5.    {  
  6.        public AreaViewEngine()  
  7.            : base()  
  8.        {  
  9.            // 视图位置匹配规则设置  
  10.            ViewLocationFormats = new string[]   
  11.            {   
  12.                "~/{0}.aspx",  
  13.                "~/{0}.ascx",  
  14.                "~/Views/{1}/{0}.aspx",  
  15.                "~/Views/{1}/{0}.ascx",  
  16.                "~/Views/Shared/{0}.aspx",  
  17.                "~/Views/Shared/{0}.ascx",    
  18.            };  
  19.            // 母版页匹配规则设置  
  20.            MasterLocationFormats = new string[]   
  21.            {   
  22.                "~/{0}.master",  
  23.                "~/Shared/{0}.master",  
  24.                "~/Views/{1}/{0}.master",  
  25.                "~/Views/Shared/{0}.master",  
  26.            };  
  27.        }  
  28.        #region override父类  
  29.        /// <summary>  
  30.        /// 寻找局部视图  
  31.        /// </summary>  
  32.        /// <param name="controllerContext">ControllerBase和HttpContextBase的上下文</param>  
  33.        /// <param name="partialViewName">局部视图名称</param>  
  34.        /// <param name="useCache">是否缓存</param>  
  35.        /// <returns>结果</returns>  
  36.        public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)  
  37.        {  
  38.            ViewEngineResult areaResult = null;  
  39.            // 判断是否存在当前的控制器分组  
  40.            if (controllerContext.RouteData.Values.ContainsKey("area"))  
  41.            {  
  42.                // 寻找局部视图  
  43.                string areaPartialName = FormatViewName(controllerContext, partialViewName);  
  44.                areaResult = base.FindPartialView(controllerContext, areaPartialName, useCache);  
  45.                if (areaResult != null && areaResult.View != null)  
  46.                {  
  47.                    return areaResult;  
  48.                }  
  49.                // 寻找共享部分的视图  
  50.                string sharedAreaPartialName = FormatSharedViewName(controllerContext, partialViewName);  
  51.                areaResult = base.FindPartialView(controllerContext, sharedAreaPartialName, useCache);  
  52.                if (areaResult != null && areaResult.View != null)  
  53.                {  
  54.                    return areaResult;  
  55.                }  
  56.            }  
  57.            // 如果均没找着,按MVC默认寻找视图。  
  58.            return base.FindPartialView(controllerContext, partialViewName, useCache);  
  59.        }  
  60.        /// <summary>  
  61.        /// 寻找视图  
  62.        /// </summary>  
  63.        /// <param name="controllerContext">控制器上下文对象</param>  
  64.        /// <param name="viewName">视图名称</param>  
  65.        /// <param name="masterName">母版页</param>  
  66.        /// <param name="useCache">是否缓存</param>  
  67.        /// <returns>结果</returns>  
  68.        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)  
  69.        {  
  70.            ViewEngineResult areaResult = null;  
  71.            if (controllerContext.RouteData.Values.ContainsKey("area"))  
  72.            {  
  73.                string areaViewName = FormatViewName(controllerContext, viewName);  
  74.                areaResult = base.FindView(controllerContext, areaViewName, masterName, useCache);  
  75.                if (areaResult != null && areaResult.View != null)  
  76.                {  
  77.                    return areaResult;  
  78.                }  
  79.                string sharedAreaViewName = FormatSharedViewName(controllerContext, viewName);  
  80.                areaResult = base.FindView(controllerContext, sharedAreaViewName, masterName, useCache);  
  81.                if (areaResult != null && areaResult.View != null)  
  82.                {  
  83.                    return areaResult;  
  84.                }  
  85.            }  
  86.                  
  87.            return base.FindView(controllerContext, viewName, masterName, useCache);  
  88.        }  
  89.        #endregion  
  90.        private static string FormatViewName(ControllerContext controllerContext, string viewName)  
  91.        {  
  92.            string controllerName = controllerContext.RouteData.GetRequiredString("controller");  
  93.            string area = controllerContext.RouteData.Values["area"].ToString();  
  94.            return string.Format("Areas/{0}/Views/{1}/{2}" , area, controllerName ,viewName);  
  95.        }  
  96.        private static string FormatSharedViewName(ControllerContext controllerContext, string viewName)  
  97.        {  
  98.            string area = controllerContext.RouteData.Values["area"].ToString();  
  99.            return string.Format("Areas/{0}/Views/Shared/{1}", area, viewName);  
  100.        }  
  101.    }  

 

如何使用呢?

 

这个就是轻车熟路了,去全局应用程序类中进行配置控件器分组、注册视图引擎,就可以了。

 

a. 设置不同的控制器项

  1. public static void RegisterRoutes(RouteCollection routes)  
  2.        {  
  3.            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  4.            // Account控制器组  
  5.            routes.CreateArea("Account", "WT.TTC.UI.Areas.Account.Controllers",  
  6.                routes.MapRoute(null, "Account/{controller}/{action}", new { controller = "Account", action = "Index" }));  
  7.            // UserCenter控制器组  
  8.            routes.CreateArea("UserCenter", "WT.TTC.UI.Areas.UserCenter.Controllers",  
  9.                routes.MapRoute("IndexPage2", "UserCenter/{controller}/{action}", new { controller = "Home", action = "Index" }));  
  10.            // root,根目录  
  11.            routes.CreateArea("Root", "WT.TTC.UI.Controllers.HomeController",  
  12.                routes.MapRoute("IndexPage3-必须唯一", "UserCenter/{controller}/{action}", new { controller = "Home", action = "Index" }));  
  13.        }  

 

b. 设置视图引擎

  1. protected void Application_Start()  
  2.         {  
  3.             // 添加视图引擎  
  4.             ViewEngines.Engines.Clear();  
  5.             ViewEngines.Engines.Add(new AreaViewEngine());  
  6.             RegisterRoutes(RouteTable.Routes);  
  7.         }  

 

输入url:

http://localhost:5459/account/account/index

http://localhost:5459/UserCenter/Home/index

 

结果:能够正常导航。一切OK结束。

 

注意一件事:

routes.MapRoute(null, "Account/{controller}/{action}".......

routes.MapRoute(“IndexPage2”, "Account/{controller}/{action}".......

routes.MapRoute("IndexPage3-必须唯一", "UserCenter/{controller}/{action}".......

 

我们发现:routes.MapRoute方法第一个参数,路由名称不能重复;或者为null值,但不推荐这么做,假如哪一天你可trace,有一个名字是不是好很多?

 

在此间中出现了一个大黄页错误:

 

未能加载类型“System.Web.Mvc.ViewPage<dynamic>”。

 

在Web.config文件的pages节点加入即可,原因应该是缺少配置,导致反射生成类型失败。

 

  1. <pages validateRequest="false" pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"  
  2.             pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"   
  3.             userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">  

原文地址:https://www.cnblogs.com/happy-Chen/p/3605232.html