在大型的ASP.NET mvc5项目中一般都有许多个功能模块,这些功能模块可以用Area(中文翻译为区域)把它们分离开来,比如:Admin,Customer,Bill。
ASP.NET MVC项目中把各个功能分为不同Area的之后每一个Area都有独立的Controller,View文件结构。这样可以把这些功能分给不同的开发者同时开发而彼此之间不会冲突,这样的文件结构各司其职,直观明了,易于维护和管理。下面我们看看怎么在ASP.NET MVC5中创建一个Area和Area直接之间链接的处理。
一、ASP.NET MVC5中创建Area区域
选中我们的ASP.NET MVC项目,右键菜单,添加=》区域,这里我们取名为Admin,在项目根目录将会生成一个Admin文件夹,如下图:
我们来看这个Area是怎么在项目的起作用的。
我们来看Global.asax.cs的代码:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
第一行的代码:AreaRegistration.RegisterAllAreas();
就是注册 ASP.NET MVC 应用程序中的所有区域。每一个区域它有自己的都有独立的Controller,View文件结构和路由配置,我们完全可以把ASP.NET MVC的区域看成一个ASP.NET MVC项目。
注意: RouteConfig.RegisterRoutes(RouteTable.Routes)
在AreaRegistration.RegisterAllAreas();
的后面。这一点很关键,你最好是不要改变这个顺序。之前我们谈到过ASP.NET MVC路由系统是按注册路由的先后顺序来匹配的,这里RegisterAllAreas在前面表示MVC路由系统会先去匹配Area中的路由配置规则,如果你改变了顺序可能会找到错误的Controller,发生意外的错误。
在ASP.NET MVC5的每个区域都有一个类:区域名+AreaRegistration,比如我们刚才建的一个Admin区域AdminAreaRegistration类:
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
这个类的作用主要是用于标示区域名称和区域Controller的路由,可以看到路由规则为"Admin/{controller}/{action}/{id}"
,前面统一跟了一个Admin。
二、在Area区域的视图之间Action的链接跳转的处理
当在ASP.NET MVC项目中使用了AreaArea区域后,会涉及到不同Area的Action链接之间相互跳转,我使用Html.ActionLink有些地方需要注意。
1、同一个Area之间跳转
在Area区域的视图中生成指向同一个Area的Action链接时,你不需要做任何处理,当你调用Html.ActionLink时MVC框架自动去找当前Area的相应路由来生成Action的链接。如下:
@Html.ActionLink("Click me", "About")
生成下面的html:
<a href="/Admin/Home/About">Click me</a>
2、不同Area之间跳转
@Html.ActionLink("Click me to go to another area", "Index", new { area = "Support" })
把Route中的area指定就可以了。
3、跳转到不带Area的Action
我们知道使用Html.ActionLink没有指定area,默认就是当前的area。有时我们需要链接到顶层的Controller的Action,就是不要带area,也很简单,只需要把area传空字符串就可以了。如下:
@Html.ActionLink("Click me to go to another area", "Index", new { area = "" })
三、使用Areas后怎样获取Area(区域)的名称
获取当前Area(区域)名称的方法是:这样,我就可以通过下面三个语句,分别获取用户当前访问的Area、Controller和Action:
ViewContext.RouteData.DataTokens["area"]
string areaName = filterContext.RouteData.DataTokens["area"] == null ? "" : filterContext.RouteData.DataTokens["area"].ToString();
string controllerName=filterContext.RouteData.Values["controller"].ToString();
string actionName=filterContext.RouteData.Values["action"].ToString();
当用户访问的是主站(根目录)时**<font style="color:rgb(255, 0, 0);">filterContext.RouteData.DataTokens["area"]</font>**
为null,因此上面代码第一句有个判断是否为null的语句。
四、设置包含Areas中的页面为默认启动页
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
// //添加此行,指定命名空间: namespaces: new string[] { "要设置Controller的命名空间" }
// namespaces: new string[] { "EmergencyWeb.Areas.EmergencyEvacuation.Controllers" }
).DataTokens.Add("Area", "Admin");
注意:使用DataTokens.Add
第二个参数是创建的区域Area名称,而不是controller名称。