Home  >  Article  >  Backend Development  >  [ASP.NET MVC Mavericks Road] 08 - Area use

[ASP.NET MVC Mavericks Road] 08 - Area use

黄舟
黄舟Original
2016-12-30 14:35:241531browse

[ASP.NET
MVC Mavericks Road]08 - Area Using

ASP.NET MVC allows the use of Areas (areas) to organize Web applications. Each Area represents a different aspect of the application. functional module. This is very useful for large projects. Area allows each functional module to have its own folder with its own Controller, View and Model, but it also adds a certain degree of difficulty to management.

Directory of this article


Create Area

Right-click the project and select Add->Area, the following dialog box for filling in Area will pop up:

[ASP.NET MVC Mavericks Road] 08 - Area use

After clicking Add, the project directory structure is as follows:

[ASP.NET MVC Mavericks Road] 08 - Area use

Similar to creating an empty MVC project structure, the Admin Area has its own Controllers, Models and Views folders, the difference is that there is an additional AdminAreaRegistration.cs file. This file defines a class called AdminAreaRegistration. Its content is as follows:

namespace MvcApplication1.Areas.Admin {
    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 }
            );
        }
    }
}

AdminAreaRegistration automatically generated by the system The class inherits from the abstract class AreaRegistration and overrides the

AreaName property and RegisterArea method. In the RegisterArea method, it defines a default route for us. We can also define other routes specific to the Admin Area in this method. But one thing to note is that if you want to name the route here, make sure it is different from the entire application.

The MapRoute method of the AreaRegistrationContext class is used the same as the MapRoute method of the RouteCollection class, except that the AreaRegistrationContext class limits the registered routes to only match the controller of the current Area. Therefore, if you add the The default namespace of the controller has been changed, and the routing system will not be able to find this controller.

The RegisterArea method does not require us to call it manually. The Application_Start method in Global.asax already has the following code to do this for us:

protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

Call the AreaRegistration.RegisterAllAreas method Let the MVC application, upon startup, look for all classes that inherit from AreaRegistration and call their RegisterArea method for each such class.

Note: Do not change the order of registration methods in Application_Start easily. If you put the RouteConfig.RegisterRoutes method before the AreaRegistration.RegisterAllAreas method, the registration of Area routes will be after the route registration. The routing system is in order. matching, so doing so will cause the Controller requesting the Area to match the wrong route.


Area operation

Adding controller, view and model in Area is the same as general addition. Here, we add a controller named Home in the Admin Area, the code is as follows:

public class HomeController : Controller {
        
    public ActionResult Index() {
        return View();
    }
}

Then we add a View for the Index Acton, the code is as follows:

@{ 
    ViewBag.Title = "Index";
    Layout = null; 
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <p>
        <h2>Admin Area Index</h2>
    </p>
</body>
</html>

Run application, and then locate the URL to /Admin/Home/Index. The following is the running result:

[ASP.NET MVC Mavericks Road] 08 - Area use

Here, We have seen that the workflow in Area is actually the same as the process in the root directory. But Area is not a completely independent workspace, let's take a look below.


Controller ambiguity issue

Just imagine, if we now also add a Controller named Home in the Controller folder of the root directory, then we By positioning the URL to /Home/Index, can the routing system match the Controller in the root directory?

After adding the HomeController to the Controllers folder in the root directory, add a View for the Index. The content is arbitrary:

...
<body>
    <p>
        <h2>Root Index</h2>
    </p>
</body>
...

The route will not be changed. We use the default route defined by the system in the RouteConfig.cs file. :

public static void RegisterRoutes(RouteCollection routes) {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

Run the program and locate the URL to /Home/Index. As a result, we will see the following error message:

[ASP.NET MVC Mavericks Road] 08 - Area use

出现这个问题是因为路由系统进行匹配的时候出现了Controller同名的歧义。

当Area被注册的时候,Area中定义的路由被限制了只寻找 Area 中的Controller,所以我们请求 /Admin/Home/Index 时能正常得到 MvcApplication1.Areas.Admin.Controllers 命名空间的 HomeController。然而我们在RouteConfig.cs文件的RegisterRoutes方法中定义的路由并没有类似的限制。

为了解决这个问题,我们需要在RouteConfig.cs文件中定义的路由中加上对应的 namespaces 参数。RouteConfig.cs 中修改后的路由如下:

public static void RegisterRoutes(RouteCollection routes) {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new[] { "MvcApplication1.Controllers" }
    );
}

运行程序,如下结果说明解决了同名歧义问题:

[ASP.NET MVC Mavericks Road] 08 - Area use

添加了 namespaces 参数后,路由系统在对这个路由进行匹配时,优先匹配指定命名空间的controller,如果匹配到则即刻停止查找,如果在指定的命名空间下没有匹配到对应的controller,再按照一般的方式进行匹配。

生成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>

 以上就是[ASP.NET MVC 小牛之路]08 - Area 使用的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn