MVC进阶学习--个性化目录结构(三)

(一) 目录结构

  MVC进阶学习--个性化目录结构(三)

  看到上面的目录结构 会有耳目一新的感觉,终于突破了原有的MVC目录结构。该目录结构除了使用原有的Controllers 文件夹之外,我们还使用了Games自定义文件夹中的Controllers。在Users文件夹中也同样还有一个Controllers文件夹,这些文件夹都是存放控制器类的。我们可以根据自己的需要建立不同的Controller 组。

  在大型项目开发的过程中,模块的数量可能会很多,仅仅只靠原有的目录结构是不能满足我们的要求的,而且扩展性也不是太好,因为思想就被束缚在它本身的结构上,扩展谈何容易。但真正的作为一个企业级架构这肯定是不行的,最起码走起来比较困难。于是控制器组,个性化的目录就是解决方案的开始。

 

(二) 扩展路由配置(RouteCollection 类的扩展)

  我们都知道 .net3.0 3.5 中出现的扩展方法使.net 出现了新的生机,我们不必在为系统方法的不适用而烦恼,也不用为其思维的束缚的叫苦不迭。扩展方法能使我们能够扩展系统中的任何一个类,给它重新添加自己想要的方法。

MVC进阶学习--个性化目录结构(三)MVC进阶学习--个性化目录结构(三)Code
 1 public class Student
 2     {
 3         private int _id;
 4 
 5         public int Id
 6         {
 7             get { return _id; }
 8             set { _id = value; }
 9         }
10 
11         private string _name;
12 
13         public string Name
14         {
15             get { return _name; }
16             set { _name = value; }
17         }
18     }

  我定义一个实体类,这个类中只有两个属相,没有任何自定方法。现在我们用扩展方法给Student添加一个Write()自定义方法

1 public static class StudentExtension
2     {
3         public static void Write(this Student stu, string name)
4         {
5             Console.WriteLine(name);
6         }
7     }

扩展方法的使用代码:

MVC进阶学习--个性化目录结构(三)MVC进阶学习--个性化目录结构(三)Code
 1  public class Test
 2     {
 3         public void Show()
 4         {
 5             Student stu = new Student();
 6             stu.Id = 1;
 7             stu.Name = "ddd";
 8             stu.Write(stu.Name);
 9         }
10     }

  注意 扩展方法必须在静态类中,而且扩展方法也必须用static修饰。扩展方法的第一个参数用this修饰,参考上面的就可以知道,当我们使用这个扩展方法的时候 参数就static 修饰方法中的非this修饰的参数,说的有点绕口。相信能够明白。

 

  RouteCollection扩展类,扩展路由设置

 1 public static class AreaRouteHelper
 2     {
 3         public static void CreateArea(this RouteCollection routes, 
 4             string areaName, 
 5             string controllerNameSpace, 
 6             params Route[] routeEntries)
 7         {
 8             foreach (Route route in routeEntries)
 9             {
10                 if (route.Constraints == null)
11                 {
12                     route.Constraints = new RouteValueDictionary();
13                 }
14 
15                 if (route.Defaults == null)
16                 {
17                     route.Defaults = new RouteValueDictionary();
18                 }
19 
20                 if (route.DataTokens == null)
21                 {
22                     route.DataTokens = new RouteValueDictionary();
23                 }
24 
25                 route.Constraints.Add("area",areaName);
26                 route.Defaults.Add("area",areaName);
27                 route.DataTokens.Add("namespaces",new string[]{controllerNameSpace});
28 
29                 if (!routes.Contains(route))
30                 {
31                     routes.Add(route);
32                 }
33             }
34         }
35     }

 

  

  对于自定义视图的关键还是如下:WebFormViewEngine 定义了视图文件的显示,我们可以继承改类从而重载覆盖父类的方法达到自己定义文件映射路径的目的

  

  1 public class AreaViewEngine:WebFormViewEngine
  2     {
  3         public AreaViewEngine()
  4             : base()
  5         {
  6             //定义页面文件或者用户控件文件的路径规则
  7             ViewLocationFormats = new string[] { 
  8                 "~/{0}.aspx",
  9                 "~/{0}.ascx",
 10                 "~/Views/{1}/{0}.aspx",
 11                 "~/Views/{1}/{0}.ascx",
 12                 "~/Views/Shared/{0}.aspx",
 13                 "~/Views/Shared/{0}.ascx"
 14             };
 15 
 16             //第一母版页文件路径规则
 17             MasterLocationFormats = new string[] { 
 18                 "~/{0}.master",
 19                 "~/Shared/{0}.master",
 20                 "~/Views/Shared/{0}.master",
 21                 "~/Views{1}/{0}.master"
 22             };
 23 
 24             PartialViewLocationFormats = ViewLocationFormats;
 25         }
 26 
 27 
 28         /// <summary>
 29         /// 匹配页面文件的,寻找相应的部分视图文件
 30         /// </summary>
 31         /// <param name="controllerContext"></param>
 32         /// <param name="partialViewName"></param>
 33         /// <param name="useCache"></param>
 34         /// <returns></returns>
 35         public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
 36         {
 37             ViewEngineResult viewResult = null;
 38             if (controllerContext.RequestContext.RouteData.Values.ContainsKey("area"))
 39             {
 40                 string areaPartialName = FormatViewName(controllerContext,partialViewName);
 41                 viewResult = base.FindPartialView(controllerContext,areaPartialName,useCache);
 42                 if (viewResult != null && viewResult.View != null)
 43                 {
 44                     return viewResult;
 45                 }
 46 
 47                 string sharedAreaPartialName = FormatPartialViewName(controllerContext, partialViewName);
 48                 viewResult = base.FindPartialView(controllerContext,sharedAreaPartialName,useCache);
 49                 if (viewResult != null && viewResult.View != null)
 50                 {
 51                     return viewResult;
 52                 }
 53             }
 54             return base.FindPartialView(controllerContext, partialViewName, useCache);
 55         }
 56 
 57         /// <summary>
 58         /// 匹配页面文件的,寻找相应的试图文件
 59         /// </summary>
 60         /// <param name="controllerContext"></param>
 61         /// <param name="viewName"></param>
 62         /// <param name="masterName"></param>
 63         /// <param name="useCache"></param>
 64         /// <returns></returns>
 65         public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
 66         {
 67             ViewEngineResult viewResult = null;
 68             if (controllerContext.RequestContext.RouteData.Values.ContainsKey("area"))
 69             {
 70                 string areaPartialName = FormatViewName(controllerContext, viewName);
 71                 viewResult = base.FindView(controllerContext, areaPartialName,masterName, useCache);
 72                 if (viewResult != null && viewResult.View != null)
 73                 {
 74                     return viewResult;
 75                 }
 76 
 77                 string sharedAreaPartialName = FormatPartialViewName(controllerContext, viewName);
 78                 viewResult = base.FindView(controllerContext, sharedAreaPartialName,masterName, useCache);
 79                 if (viewResult != null && viewResult.View != null)
 80                 {
 81                     return viewResult;
 82                 }
 83             }
 84             return base.FindView(controllerContext, viewName, masterName, useCache);
 85         }
 86 
 87         /// <summary>
 88         /// 这个匹配一般的页面文件或用户控件路径
 89         /// </summary>
 90         /// <param name="context"></param>
 91         /// <param name="viewName"></param>
 92         /// <returns></returns>
 93         public string FormatViewName(ControllerContext context, string viewName)
 94         {
 95             //根据路由的参数值获得控制器的名称
 96             string controllerName = context.RouteData.GetRequiredString("controller");
 97 
 98             //根据路由的参数获得控制器组的名称
 99             string area = context.RequestContext.RouteData.Values["area"].ToString();
100             return "Area/" + area + "/Views/" + controllerName + "/"+viewName ;
101         }
102 
103         /// <summary>
104         /// 这个一般匹配母版页的文件路径
105         /// </summary>
106         /// <param name="context"></param>
107         /// <param name="viewName"></param>
108         /// <returns></returns>
109         public string FormatPartialViewName(ControllerContext context, string viewName)
110         {
111             //根据路由的参数获得控制器组的名称
112             string area = context.RequestContext.RouteData.Values["area"].ToString();
113             return "Area/" + area + "/Views/Shared/" + viewName;
114         }
115 
116     }

 

 

 

上一篇:MVC进阶学习--HtmlHelper控件解析(三)


下一篇:Linux Shell脚本实现批量PING测试