Deep understanding of ASP. NET MVC (4)

Source: Internet
Author: User
Tags httpcontext

Series Catalogue

Datatokens and areas mechanisms

So far the Route object has only left the Datatokens attribute not involved, in fact the core of this areas mechanism.

Datatokens is actually a routevaluedictionary, when constructed in the Route structure with the MapRoute method, You can pass an array of namespaces strings, which will be constructed into the datatokens["namespaces" of the Route object, and its value will is preferred by the MVC framework to find the appropriate controller in the corresponding namespace. If the controller is found in the specified namespace, it does not matter if the controller with the same name in the other namespace is case sensitive, and if the controller is not found in the specified namespace, it will be looked up in all referenced assemblies. If a controller with duplicate names appears, multiple matching errors will occur. This behavior is defaultcontrollerfactory implemented, and about Defaultcontrollerfactory will be analyzed later.

Areas mechanism is such a mechanism: in different area can have the same name of the controller, that is, the controller's name can be repeated! This way, the entire Web application can be divided into several modules, each of which is an area, each area is independent of each other, and can be independently defined by a developer as a URL or controller without affecting other areas.

For example: There are two modules for administrators and users, which may require the following URLs:

Admin/home/index

User/home/index

You can then create two area:admin and user with the VS Integrated area build template, respectively, by two developers, all of them need to use the HomeController and index methods, with the areas mechanism, HomeController are placed in two different namespaces, so there is no conflict.

Here you may be vaguely aware of some kind of relationship between datatokens and areas mechanisms. What did you do when vs created areas?

First, in each area the controller will be placed in a namespace, for example: MyAppName.Areas.Admin.Controllers;

Second, create a Arearegistration inheritance class for each area, if the admin area will be adminarearegistration. In this class, override the AreaName property and the Registerarea method:

12345678 public override void RegisterArea(AreaRegistrationContext context){    context.MapRoute(        "Admin_default",        "Admin/{controller}/{action}/{id}",        new { action = "Index", id = UrlParameter.Optional }    );}

You can see that the Maproute method is also called in the Registerarea method to register the route. It is important to note that this MapRoute , while also manipulating the global routing table , has a slightly different implementation:

1. The URL pattern that is first set begins with the area name, which is necessary, after all, the URL pattern is finally placed in the global;

2. It will set datatokens["namespaces" to the namespace of the current area, such as myappname.areas.admin.*. As a result, when a request arrives, Defaultcontrollerfactory will take precedence over the name space to find the controller. It also adds a datatokens["Usenamespacefallback"] and is set to False to succeed if and only if there is a required controller in the namespace where the settings are displayed. Controllers with the same name in other namespaces will not be valid;

3. Finally, a key value called datatokens["area" is added and set to the current area name, which is used for the reverse mapping (outbounding) URL. so the "area" key in MVC has a special purpose, so it cannot be used for URL pattern parameters.

There is a conflict in the areas mechanism that needs attention. Since the routing table has only one sheet, if the current URL is mapped to "root area" (that is, in the global domain), the controller will be looked up from all of the current namespaces, and more than one match is likely to be found. The solution is to set the precedence namespace for Datatokens when routing is set in Globla.asax.cs.

further expansion

After a deep understanding of the routing mechanism, some customizations are made.

Custom RouteBase

With the previous analysis, it can be known that the route (inherited from RouteBase) needs to provide a routedata when inbound, so routebase defines the Getroutedata method, which we can implement ourselves; The GetVirtualPath method is used for outbound. Therefore, as long as the two methods are implemented, a routebase implementation can be accomplished. For example: When you want to change an old site into a new MVC-based architecture, and do not want to invalidate the original URL, a simple solution can be like this:

1234567891011121314151617181920212223242526272829 public class LegacyUrlsRoute : RouteBase{    // In practice, you might fetch these from a database    // and cache them in memory    private static string[] legacyUrls = new string[] {    "~/articles/may/zebra-danio-health-tips.html",    "~/articles/VelociraptorCalendar.pdf",    "~/guides/tim.smith/BuildYourOwnPC_final.asp"    };    public override RouteData GetRouteData(HttpContextBase httpContext)    {        string url = httpContext.Request.AppRelativeCurrentExecutionFilePath;        if(legacyUrls.Contains(url, StringComparer.OrdinalIgnoreCase)) {            RouteData rd = new RouteData(this, new MvcRouteHandler());            rd.Values.Add("controller", "LegacyContent");            rd.Values.Add("action", "HandleLegacyUrl");            rd.Values.Add("url", url);            return rd;        }        else        return null; // Not a legacy URL    }    public override VirtualPathData GetVirtualPath(RequestContext requestContext,        RouteValueDictionary values)    {        // This route entry never generates outbound URLs        return null;    }}

Custom Iroutehandler

Typically in the MVC framework, the Iroutehandler is implemented by Mvcroutehandler, the entrance to this MVC framework. Still, we can define a iroutehandler ourselves. This can be considered when we need to optimize the processing of certain requests. Because the custom implementation of Iroutehandler means that the MVC framework will be ignored. For example, the following implementation:

123456789101112131415 public class HelloWorldHandler : IRouteHandler{    public IHttpHandler GetHttpHandler(RequestContext requestContext)    {        return new HelloWorldHttpHandler();    }    private class HelloWorldHttpHandler : IHttpHandler    {        public bool IsReusable { get { return false; } }        public void ProcessRequest(HttpContext context)        {            context.Response.Write("Hello, world!");        }    }}

Fruits of labor, reproduced please specify the source: http://www.cnblogs.com/P_Chou/archive/2010/11/15/details-asp-net-mvc-04.html

Deep understanding of ASP. NET MVC (4)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.