ASP.NET MVC Area 的使用

本文探讨了在ASP.NET MVC大型项目中如何组织Area结构以避免Controller命名冲突,并重点讲解了如何通过指定命名空间解决路由匹配多Controller的问题,包括Area的路由配置和URL生成技巧。
摘要由CSDN通过智能技术生成

应用场景:

ASP.NET MVC中,是依靠某些文件夹以及类的固定命名规则去组织model实体层,views视图层和控制层的。如果是大规模的应用程序,经常会由不同功能的模块组成,而每个功能模块都由MVC中的三层所构成,因此,随着应用程序规模的增大,如何组织这些不同功能模块中的MVC三层的目录结构,有时对开发者来说显得是种负担。

另一个问题就是Controller不允許有相同命名的存在,偏偏模块中常有父子关系,有时子模块命名相同就会造成错误。

幸运的是,ASP.NET MVC允许开发者将应用划分为“区域”(Area)的概念。
Area(区域)简介:

每个区域都是按照asp.net mvc的规定对文件目录结构和类的命名规则进行命名。添加方法也很简单,右击项目,点击添加区域,在弹出框里写上Area的名称点击确定即可。

1、新建 Area:右键 -> Add -> Area…
2、继承 AreaRegistration,配置对应此 Area 的路由
3、在 Global 中通过 AreaRegistration.RegisterAllAreas(); 注册此 Area
4、有了 Area,就一定要配置路由的命名空间

Area的路由

在添加好了区域之后,vs会自动帮我们注册Area的路由信息:

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 { controller = "Console", action = "Login", id = UrlParameter.Optional }
        );
    }
}

问题

试想如果这时候有这样的情形:

如果有一个Area叫CustomerManage,在它的下面有一个Controller名字叫做Customer。

另外我在顶层也有一个Controller,名字也叫Customer。

输入http://localhost:2024/CustomerManage/Customer,我们却能够正常地访问到DaleCloud.Web.Areas.CustomerManage.Controllers.CustomerController。原来在注册Area的路由时,如果没有填写命名空间的话,则会默认使用Area所在的命名空间。如此一来,使用Area的路由在寻找Controller时,只会在Area所在的空间下寻找相应的Controller。

那么我们在输入http://localhost/Customer,我们得到的将是一个异常:

在这里插入图片描述
错误提示: 找到多个与名为“Customer”的控制器匹配的类型。如果为此请求(“{controller}/{action}/{id}”)提供服务的路由没有指定命名空间以搜索与此请求相匹配的控制器,则会发生这种情况。如果是这样,请通过调用带有 ‘namespaces’ 参数的 “MapRoute” 方法的重载来注册此路由。
“Customer”请求找到下列匹配的控制器:
DaleCloud.Web.Controllers.CustomerController
DaleCloud.Web.Areas.CustomerManage.Controllers.CustomerController

个人理解:
根据RouteConfig的路由规则“{controller}/{action}/{id}”提供服务的路由没有指定命名空间,所以会匹配项目中所有命名空间下叫"Customer"的控制器,出现多个同名就会报错。
解决办法 :
在顶层路由映射的时候主动加上命名空间"DaleCloud.Web.Controllers"。 如果浏览器的URL符合RouteConfig的路由规则“{controller}/{action}/{id}",则它只会访问命名空间"DaleCloud.Web.Controllers"下面的控制器名。

再次访问 http://localhost:2024/CustomerManage/Customer 会匹配DaleCloud.Web.Controllers命名空间下的CustomerController。

public static void RegisterRoutes(RouteCollection routes)
{
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
     routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Customer", action = "Index", id = UrlParameter.Optional },// Parameter defaults
        new[] { "DaleCloud.Web.Controllers" }// Namespaces 引入默认的命名空间
        );
 
}

让起始页为某Area的页面:

修改RoutConfig代码:

	
public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Console", action = "Login", id = UrlParameter.Optional }
    ).DataTokens.Add("area","Admin");
}

注意后面的DataTokens.Add方法!

生成Area URL链接

关于Area的URL链接生成,可以分为这么三种情况:第一种是在当前Area生成指向当前Area的链接;第二种是生成指向其他Area的链接;第三种是在某个Area中生成指向根目录的链接。下面是这三种情况生成链接的方法,使用的路由定义是系统默认的。

如果要在Area中生成当前Area的URL链接,直接用下面的方法就行:

@Html.ActionLink(“Click me”, “About”)

它根据当前所在的Area和Controller会生成如下Html代码:

<a href=“/Admin/Home/About”>Click me</a>

如果要生成其他Area的URL链接,则需要在Html.ActionLink方法的匿名参数中使用一个名为area的变量来指定要生成链接的Area名称,如下:

@Html.ActionLink(“Click me to go to another area”, “Index”, new { area = “Support” })

它会根据被指定的Area去找路由的定义,假定在Support Area中定义了对应的路由,那么它会生成如下链接:

<a href=“/Support/Home/Index”>Click me to go to another area</a>

如果要在当前Area生成指根目录某个controller的链接,那么只要把area变量置成空字符串就行,如下:

@Html.ActionLink(“Click me to go to top-level part”, “Index”, new { area = “” })

它会生成如下Html链接:

<a href=“/Home/Index”>Click me to go to top-level part</a>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值