域间路由的MVC5 [英] Domain Routing in MVC5

查看:100
本文介绍了域间路由的MVC5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有这些帮助我对类似的事情了几篇文章,但没有。

我有指向同一个应用程序的多个域的单一Web应用程序。我想知道我怎么能基于正试图访问Web应用程序域的路由映射到一个特定的控制器。

我试过目前是没有成功以下。

  routes.MapRoute(
    名称:WowPoetry
    网址:wowpoetry.org/{action}/{id},
    默认:新{控制器=哗,行动=索引,ID = UrlParameter.Optional}
);


解决方案

我结束了下面这个教程要达到什么我想和异常的我用来做域内路由,而不是子域的路由。

域路由教程ASP。净MVC

实施

  routes.Add(新DomainRoute(wowpoetry.org,,新{控制器=哗,行动=索引}));

DomainData.cs

 公共类DomainData
{
    公共字符串协议{搞定;组; }
    公共字符串主机名{获得;组; }
    公共字符串片段{搞定;组; }
}

DomainRoute.cs

 公共类DomainRoute:路线
{
    私人正则表达式domainRegex;
    私人正则表达式pathRegex;    公共字符串域{搞定;组; }    公共DomainRoute(字符串域名,URL字符串,RouteValueDictionary默认)
        :基地(URL,默认,新MvcRouteHandler())
    {
        域=域名;
    }    公共DomainRoute(字符串域名,URL字符串,RouteValueDictionary违约,IRouteHandler routeHandler)
        :基地(URL,默认,routeHandler)
    {
        域=域名;
    }    公共DomainRoute(字符串域名,URL字符串,对象的默认值)
        :基地(网址,新RouteValueDictionary(默认),新MvcRouteHandler())
    {
        域=域名;
    }    公共DomainRoute(字符串域名,URL字符串,对象违约,IRouteHandler routeHandler)
        :基地(网址,新RouteValueDictionary(默认),routeHandler)
    {
        域=域名;
    }    公众覆盖的RouteData GetRouteData(HttpContextBase的HttpContext)
    {
        //建立正则表达式
        domainRegex ​​= CreateRegex(域);
        pathRegex ​​= CreateRegex(URL);        //请求信息
        字符串requestDomain = httpContext.Request.Headers [主机];
        如果(!string.IsNullOrEmpty(requestDomain))
        {
            如果(requestDomain.IndexOf(:)大于0)
            {
                requestDomain = requestDomain.Substring(0,requestDomain.IndexOf(:));
            }
        }
        其他
        {
            requestDomain = httpContext.Request.Url.Host;
        }
        串requestPath = httpContext.Request.Ap prelativeCurrentExecutionFilePath.Substring(2)+
                             httpContext.Request.PathInfo;        //匹配域和路线
        比赛domainMatch = domainRegex.Match(requestDomain);
        比赛pathMatch = pathRegex.Match(requestPath);        //路由数据
        数据的RouteData = NULL;
        如果(domainMatch.Success&放大器;&放大器; pathMatch.Success&放大器;&放大器;!requestDomain.ToLower()=tg.local与&&放大器;
            requestDomain.ToLower()=tg.terrasynq.net&放大器;!&安培; requestDomain.ToLower()=www.townsg​​ossip.com&放大器;!&安培;
            requestDomain.ToLower()!=townsg​​ossip.com)
        {
            数据=新的RouteData(这一点,RouteHandler);            //首先添加默认值
            如果(默认值!= NULL)
            {
                的foreach(KeyValuePair<字符串对象>在默认项)
                {
                    data.Values​​ [item.Key] = item.Value;
                }
            }            //迭代匹配域组
            的for(int i = 1; I< domainMatch.Groups.Count;我++)
            {
                群组= domainMatch.Groups [I]
                如果(group.Success)
                {
                    字符串键= domainRegex.GroupNameFromNumber(I)                    如果(string.IsNullOrEmpty(键)及!&安培;!char.IsNumber(键,0))
                    {
                        如果(!string.IsNullOrEmpty(group.Value))
                        {
                            data.Values​​ [关键] = group.Value;
                        }
                    }
                }
            }            //迭代匹配路径组
            的for(int i = 1; I< pathMatch.Groups.Count;我++)
            {
                群组= pathMatch.Groups [I]
                如果(group.Success)
                {
                    字符串键= pathRegex.GroupNameFromNumber(I)                    如果(string.IsNullOrEmpty(键)及!&安培;!char.IsNumber(键,0))
                    {
                        如果(!string.IsNullOrEmpty(group.Value))
                        {
                            data.Values​​ [关键] = group.Value;
                        }
                    }
                }
            }
        }        返回的数据;
    }    公众覆盖VirtualPathData GetVirtualPath(RequestContext的的RequestContext,RouteValueDictionary值)
    {
        返回base.GetVirtualPath(RequestContext的,RemoveDomainTokens(值));
    }    公共DomainData GetDomainData(RequestContext的的RequestContext,RouteValueDictionary值)
    {
        //主机构建
        字符串主机名=域名;
        的foreach(KeyValuePair<字符串对象>对价值观)
        {
            主机名= hostname.Replace({+ pair.Key +},pair.Value.ToString());
        }        //返回域数据
        返回新DomainData
        {
            协议=HTTP,
            HOSTNAME =主机名,
            片段=
        };
    }    私人正则表达式CreateRegex(字符串源)
    {
        //执行替换
        来源= source.Replace(/,@\\ /?);
        来源= source.Replace(@\\?,);
        来源= source.Replace( - ,@\\ - ?);
        来源= source.Replace({,@(小于?);
        来源= source.Replace(},@>([A-ZA-Z0-9 _ \\ - ] *)));        返回新正则表达式(^+源+$);
    }    私人RouteValueDictionary RemoveDomainTokens(RouteValueDictionary值)
    {
        VAR tokenRegex ​​=
            新正则表达式(
                @\"({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?({[a-zA-Z0-9_\\-]*})*\\.?\\/?\");
        比赛tokenMatch = tokenRegex.Match(域);
        的for(int i = 0; I< tokenMatch.Groups.Count;我++)
        {
            群组= tokenMatch.Groups [I]
            如果(group.Success)
            {
                字符串键= group.Value.Replace({,).Replace(},);
                如果(values​​.ContainsKey(键))
                    values​​.Remove(键);
            }
        }        返回值;
    }
}

I realize there are a few articles on similar things but none of which has helped me.

I have a single web app with multiple domains pointing to the same app. I would like to know how I can map a route to a specific controller based on the domain that is trying to access the web app.

What I currently tried is the following with no success.

routes.MapRoute(
    name: "WowPoetry",
    url: "wowpoetry.org/{action}/{id}",
    defaults: new { controller = "Wow", action = "Index", id = UrlParameter.Optional }
);

解决方案

I ended up following this tutorial to achieve what I wanted to with the exception of I used to to do domain routing and not subdomain routing.

Domain Routing Tutorial ASP.Net MVC

Implementation:

routes.Add(new DomainRoute("wowpoetry.org", "", new { controller = "Wow", action = "Index" }));

DomainData.cs

public class DomainData
{
    public string Protocol { get; set; }
    public string HostName { get; set; }
    public string Fragment { get; set; }
}

DomainRoute.cs

public class DomainRoute : Route
{
    private Regex domainRegex;
    private Regex pathRegex;

    public string Domain { get; set; }

    public DomainRoute(string domain, string url, RouteValueDictionary defaults)
        : base(url, defaults, new MvcRouteHandler())
    {
        Domain = domain;
    }

    public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
        : base(url, defaults, routeHandler)
    {
        Domain = domain;
    }

    public DomainRoute(string domain, string url, object defaults)
        : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
    {
        Domain = domain;
    }

    public DomainRoute(string domain, string url, object defaults, IRouteHandler routeHandler)
        : base(url, new RouteValueDictionary(defaults), routeHandler)
    {
        Domain = domain;
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        // Build regex
        domainRegex = CreateRegex(Domain);
        pathRegex = CreateRegex(Url);

        // 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;
        }
        string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) +
                             httpContext.Request.PathInfo;

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

        // Route data
        RouteData data = null;
        if (domainMatch.Success && pathMatch.Success && requestDomain.ToLower() != "tg.local" &&
            requestDomain.ToLower() != "tg.terrasynq.net" && requestDomain.ToLower() != "www.townsgossip.com" &&
            requestDomain.ToLower() != "townsgossip.com")
        {
            data = new RouteData(this, RouteHandler);

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

            // Iterate matching domain groups
            for (int i = 1; i < domainMatch.Groups.Count; i++)
            {
                Group group = domainMatch.Groups[i];
                if (group.Success)
                {
                    string key = domainRegex.GroupNameFromNumber(i);

                    if (!string.IsNullOrEmpty(key) && !char.IsNumber(key, 0))
                    {
                        if (!string.IsNullOrEmpty(group.Value))
                        {
                            data.Values[key] = group.Value;
                        }
                    }
                }
            }

            // 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;
                        }
                    }
                }
            }
        }

        return data;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return base.GetVirtualPath(requestContext, RemoveDomainTokens(values));
    }

    public DomainData GetDomainData(RequestContext requestContext, RouteValueDictionary values)
    {
        // Build hostname
        string hostname = Domain;
        foreach (KeyValuePair<string, object> pair in values)
        {
            hostname = hostname.Replace("{" + pair.Key + "}", pair.Value.ToString());
        }

        // Return domain data
        return new DomainData
        {
            Protocol = "http",
            HostName = hostname,
            Fragment = ""
        };
    }

    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 + "$");
    }

    private RouteValueDictionary RemoveDomainTokens(RouteValueDictionary values)
    {
        var tokenRegex =
            new Regex(
                @"({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?({[a-zA-Z0-9_\-]*})*\.?\/?");
        Match tokenMatch = tokenRegex.Match(Domain);
        for (int i = 0; i < tokenMatch.Groups.Count; i++)
        {
            Group group = tokenMatch.Groups[i];
            if (group.Success)
            {
                string key = group.Value.Replace("{", "").Replace("}", "");
                if (values.ContainsKey(key))
                    values.Remove(key);
            }
        }

        return values;
    }
}

这篇关于域间路由的MVC5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆