(一) 目录结构
看到上面的目录结构 会有耳目一新的感觉,终于突破了原有的MVC目录结构。该目录结构除了使用原有的Controllers 文件夹之外,我们还使用了Games自定义文件夹中的Controllers。在Users文件夹中也同样还有一个Controllers文件夹,这些文件夹都是存放控制器类的。我们可以根据自己的需要建立不同的Controller 组。
在大型项目开发的过程中,模块的数量可能会很多,仅仅只靠原有的目录结构是不能满足我们的要求的,而且扩展性也不是太好,因为思想就被束缚在它本身的结构上,扩展谈何容易。但真正的作为一个企业级架构这肯定是不行的,最起码走起来比较困难。于是控制器组,个性化的目录就是解决方案的开始。
(二) 扩展路由配置(RouteCollection 类的扩展)
我们都知道 .net3.0 3.5 中出现的扩展方法使.net 出现了新的生机,我们不必在为系统方法的不适用而烦恼,也不用为其思维的束缚的叫苦不迭。扩展方法能使我们能够扩展系统中的任何一个类,给它重新添加自己想要的方法。
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
}
扩展方法的使用代码:
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
}