MVC 4 DomainRoute以使用面积从RouteTable错误的实例(MVC 4 Domai

2019-09-28 14:03发布

我有一个ASP.NET MVC应用程序4,我有两个方面:

  • 后台
  • 注册

我有一类叫做DomainRoute ,它使路由整个子域的区域:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using System.Web.Routing;

namespace Admin.Web.PresentationLogic
{
    /// <summary>
    /// DomainRoute is an extension of the default Route, that makes it possible to route domains and subdomains the specific controllers.
    /// </summary>
    public class DomainRoute : Route
    {
        private string _subDomain;

        private string[] _namespaces;

        /// <summary>
        /// Initializes a new instance of the <see cref="DomainRoute"/> class.
        /// </summary>
        /// <param name="subDomain">The sub domain.</param>
        /// <param name="url">The URL format.</param>
        /// <param name="defaults">The defaults.</param>
        public DomainRoute(string subDomain, string url, RouteValueDictionary defaults)
            : base(url, defaults, new MvcRouteHandler())
        {
            this._subDomain = subDomain;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DomainRoute" /> class.
        /// </summary>
        /// <param name="subDomain">The sub domain.</param>
        /// <param name="url">The URL format.</param>
        /// <param name="defaults">The defaults.</param>
        /// <param name="namespaces">The namespaces.</param>
        public DomainRoute(string subDomain, string url, RouteValueDictionary defaults, string[] namespaces)
            : base(url, defaults, new MvcRouteHandler())
        {
            this._subDomain = subDomain;
            this._namespaces = namespaces;
        }

        /// <summary>
        /// Returns information about the requested route.
        /// </summary>
        /// <param name="httpContext">An object that encapsulates information about the HTTP request.</param>
        /// <returns>
        /// An object that contains the values from the route definition.
        /// </returns>
        public override RouteData GetRouteData(System.Web.HttpContextBase httpContext)
        {
            // Request information
            string requestDomain = httpContext.Request.Headers["HOST"];

            if (!string.IsNullOrEmpty(requestDomain))
            {
                if (requestDomain.IndexOf(":") > 0)
                {
                    requestDomain = requestDomain.Substring(0, requestDomain.IndexOf(":"));
                }
            }
            else
            {
                requestDomain = httpContext.Request.Url.Host;
            }

            var index = requestDomain.IndexOf(".");

            if (index < 0)
            {
                return RouteTable.Routes["Default"].GetRouteData(httpContext);
            }

            var subDomain = requestDomain.Substring(0, index);

            if (!String.IsNullOrWhiteSpace(subDomain))
            {
                if (this._subDomain.Equals(subDomain, StringComparison.InvariantCultureIgnoreCase))
                {
                    RouteData data = new RouteData(this, this.RouteHandler);

                    // Add defaults first 
                    if (Defaults != null)
                    {
                        foreach (KeyValuePair<string, object> item in Defaults)
                        {
                            data.Values[item.Key] = item.Value;
                        }
                    }

                    var pathRegex = this.CreateRegex(Url);
                    var requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;

                    // Match domain and route
                    Match pathMatch = pathRegex.Match(requestPath);

                    // Iterate matching path groups 
                    for (int i = 1; i < pathMatch.Groups.Count; i++)
                    {
                        Group group = pathMatch.Groups[i];
                        if (group.Success)
                        {
                            string key = pathRegex.GroupNameFromNumber(i);
                            if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
                            {
                                if (!string.IsNullOrEmpty(group.Value))
                                {
                                    data.Values[key] = group.Value;
                                }
                            }
                        }
                    }

                    if (!data.Values.ContainsKey("action"))
                    {
                        data.Values.Add("action", "Index");
                    }

                    data.DataTokens["Namespaces"] = this._namespaces;
                    data.DataTokens["area"] = data.Values["area"] ?? this._subDomain;

                    return data;
                }
            }

            return RouteTable.Routes["Default"].GetRouteData(httpContext);
        }

        /// <summary>
        /// Creates the regex.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns>Returns the Regex for the source.</returns>
        private Regex CreateRegex(string source)
        {
            // Perform replacements
            source = source.Replace("/", @"\/?");
            source = source.Replace(".", @"\.?");
            source = source.Replace("-", @"\-?");
            source = source.Replace("{", @"(?<");
            source = source.Replace("}", @">([a-zA-Z0-9_]*))");

            return new Regex("^" + source + "$");
        }
    }
}

当我注册领域,我这样做:

context.Routes.Add("Signup_default", 
    new DomainRoute("signup", "{controller}/{action}/{id}", 
    new RouteValueDictionary(new { area = "Signup", controller = "Home", action = "Index", id = UrlParameter.Optional }), 
    new string[] { "Admin.Web.Areas.Signup.Controllers" }));

所以,问题与的方式做DomainRouteGetRouteData执行方法。

每当我尝试访问signup.localhost的实例DomainRoute类是我注册后台区域时使用的一个。

我试图禁用后台区域,然后注册区域合作。

它采用的实例DomainRoute首先发生在RouteTable

我在想什么?

Answer 1:

我缺少的概念RouteCollection

步调试到.NET源之后,我意识到,在我的DomainRoute ,如果子域不匹配,而不是返回默认路由数据,我应该返回null

这是ASP.NET路由决定使用哪一个的方式-通过调用GetRouteDataHttpContext “我的比赛,让特定的路线弄清楚,如果HttpContext ?”



文章来源: MVC 4 DomainRoute to Area uses wrong instance from RouteTable