首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按域划分的ASP.NET MVC IgnoreRoute()

按域划分的ASP.NET MVC IgnoreRoute()
EN

Stack Overflow用户
提问于 2018-02-14 18:15:35
回答 3查看 1.3K关注 0票数 9

更新:为了简洁重新措辞.

对于一个ASP.NET MVC项目,是否有可能让web.config重写规则优先于MVC的RegisterRoutes()调用,或者IgnoreRoute是否可以只为特定的域调用?

我有一个MVC应用程序,它接受跨多个域(mydomain.com和otherdomain.com)的通信,应用程序根据请求的主机(即多租户)提供不同的内容。

我在web.config中配置了一个URL重写(反向代理),它应该只适用于特定的主机:

代码语言:javascript
运行
复制
<rule name="Proxy" stopProcessing="true">
        <match url="proxy/(.*)" />
        <action type="Rewrite" url="http://proxydomain.com/{R:1}" />
        <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_HOST}" pattern="^(mydomain\.com|www\.mydomain\.com)$" />
        </conditions>
        <serverVariables>
            <set name="HTTP_X_UNPROXIED_URL" value="http://proxydomain.com/{R:1}" />
            <set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
            <set name="HTTP_X_ORIGINAL_HOST" value="{HTTP_HOST}" />
            <set name="HTTP_ACCEPT_ENCODING" value="" />
        </serverVariables>
    </rule>

但是,如果web.config配置的路由从应用程序的RegisterRoutes()方法中被忽略,则MVC应用程序似乎只有在以下情况下才会遵守它们:

代码语言:javascript
运行
复制
routes.IgnoreRoute("proxy");

不幸的是,将忽略的内容应用于两个域()。非常感谢的建议..。

EN

回答 3

Stack Overflow用户

发布于 2018-02-22 14:05:30

可以只为特定的域调用IgnoreRoute吗?

是的。但是,由于默认情况下.NET路由完全忽略域,因此需要自定义路由以使IgnoreRoute特定于域。

虽然这是RouteBase做的,但最简单的解决方案是创建一个自定义路由约束,并使用它来控制特定路由将匹配的域。路由约束可以与现有的MapRouteMapPageRouteIgnoreRoute扩展方法一起使用,因此这是对现有配置的最小侵入性修复。

DomainConstraint

代码语言:javascript
运行
复制
    public class DomainConstraint : IRouteConstraint
    {
        private readonly string[] domains;

        public DomainConstraint(params string[] domains)
        {
            this.domains = domains ?? throw new ArgumentNullException(nameof(domains));
        }

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, 
            RouteValueDictionary values, RouteDirection routeDirection)
        {
            string domain =
#if DEBUG
                // A domain specified as a query parameter takes precedence 
                // over the hostname (in debug compile only).
                // This allows for testing without configuring IIS with a 
                // static IP or editing the local hosts file.
                httpContext.Request.QueryString["domain"]; 
#else
                null;
#endif
            if (string.IsNullOrEmpty(domain))
                domain = httpContext.Request.Headers["HOST"];

            return domains.Contains(domain);
        }
    }

请注意,为了测试目的,在以调试模式编译应用程序时,上述类接受查询字符串参数。这允许您使用类似于

代码语言:javascript
运行
复制
http://localhost:63432/Category/Cars?domain=mydomain.com

要在本地测试约束,无需配置本地web服务器和主机文件。此调试特性被排除在发行版构建之外,以防止生产应用程序中可能的bug(漏洞)。

用法

代码语言:javascript
运行
复制
public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // This ignores Category/Cars for www.mydomain.com and mydomain.com
        routes.IgnoreRoute("Category/Cars", 
            new { _ = new DomainConstraint("www.mydomain.com", "mydomain.com") });

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

注意:存在一个重载,它在所有内置路由扩展(包括IgnoreRoute和区域路由)上接受constraints参数。

参考资料:https://stackoverflow.com/a/48602769

票数 3
EN

Stack Overflow用户

发布于 2018-02-20 12:55:44

不要使用IgnoreRoute,请使用忽略

代码语言:javascript
运行
复制
routes.Ignore('url pattern here')
票数 0
EN

Stack Overflow用户

发布于 2018-02-22 09:54:19

是否有可能让web.config重写规则优先于MVC的RegisterRoutes()

是。请注意,有一些IIS重写与ASP.NET路由的区别

  1. URL重写用于在Web服务器处理请求之前操作URL路径。URL重写模块不知道哪个处理程序最终将处理重写的URL。此外,实际的请求处理程序可能不知道URL已被重写。
  2. ASP.NET路由用于根据请求的URL路径向处理程序发送请求。与URL重写不同,路由模块知道处理程序,并选择应该为请求的URL生成响应的处理程序。您可以认为ASP.NET路由是一种高级的处理程序映射机制。

可以只为特定的域调用IgnoreRoute吗?

根据MSDN,您可以使用接受url作为参数的版本。,但是对于相同的域!考虑到在ASP.NET MVC应用程序中使用多个域时存在一些缺点:

  • 所有的路由逻辑都是硬编码的:如果您想要添加一个新的可能的路由,则必须对其进行编码。
  • ASP.NET MVC基础架构基于VirtualPathData类。只有URL路径中的令牌用于路由。

如果您想要一个单独的MVC应用程序来处理多个域,并且对每个域进行不同的路由,那么您需要处理的是不受限制的MVC路由。然而,这是可能的RouteBase

现在,让我们讨论以下内容:

routes.IgnoreRoute("proxy");,它将忽略应用于两个域。

我相信这个规则并不完美,因为处理达到了ASP.NET路由!可能的原因可以在ServiceModel标签中web.config中找到。添加serviceHostingEnvironment代码如下所示:

代码语言:javascript
运行
复制
<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

这将允许通过IIS处理路由。

还可以将<match url="proxy/(.*)" />更改为<match url="^proxy/(.*)" /> (有一个额外的^),这是很普遍的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48793739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档