时间:2018-02-14 18:15:36

标签: asp.net asp.net-mvc iis azure-web-sites orchardcms

更新:重写简洁......

使用ASP.NET MVC项目,是否可以让 web.config 重写规则优先于MVC的RegisterRoutes()调用,或者只能调用IgnoreRoute具体领域?

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

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

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

然而,MVC应用程序似乎只会尊重 web.config 配置的路由,如果它们从应用程序的RegisterRoutes()方法中被忽略:

routes.IgnoreRoute("proxy");

然后,不幸的是,将忽略应用于两个域。建议非常感谢...

3 个答案:

答案 0 :(得分:1)

  

只能为特定域调用IgnoreRoute吗?

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

虽然possible to subclass RouteBase执行此操作,但最简单的解决方案是生成custom route constraint并使用它来控制特定路由匹配的域。路径约束可以与现有的MapRouteMapPageRouteIgnoreRoute扩展方法一起使用,因此这是对现有配置的最小入侵修复。

DomainConstraint

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

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

的URL
http://localhost:63432/Category/Cars?domain=mydomain.com

在本地测试约束,而无需配置本地Web服务器和hosts文件。此调试功能不在发布版本中,以防止生产应用程序中可能存在的错误(漏洞)。

用法

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

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

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

答案 1 :(得分:0)

请使用忽略

代替IgnoreRoute
routes.Ignore('url pattern here')

答案 2 :(得分:0)

  

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

是。请注意,有一些 Differences Between IIS URL Rewriting and ASP.NET Routing

  1. URL重写用于在请求之前操作URL路径 由Web服务器处理。 URL重写模块不知道 哪个处理程序最终将处理重写的URL。在 另外,实际的请求处理程序可能不知道URL有 被重写。
  2. ASP.NET路由用于根据请求向处理程序分派请求 请求的URL路径。与URL重写相反,路由 module知道处理程序并选择应该处理的处理程序 为请求的URL生成响应。你可以想到ASP.NET 路由作为高级处理程序映射机制。
  3.   

    只能针对特定域调用IgnoreRoute吗?

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

    • 所有路由逻辑都是硬编码的:如果您想添加新的可能 路线,你必须为它编码。
    • ASP.NET MVC基础架构基于VirtualPathData工作 类。只有URL路径中的标记用于路由。

    如果你想拥有一个处理多个域的MVC应用程序,并以不同方式对每个域进行路由,则需要处理开箱即用的MVC路由。但是,这可能是using a custom site route inheriting from RouteBase

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

      

    routes.IgnoreRoute("proxy");这适用于两者   域。

    我认为规则无法正常运行,因为处理到达 ASP.NET路由!可能的原因可以在 web.config 中的ServiceModel标记中找到。添加如下所示的serviceHostingEnvironment代码:

    <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
    

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

    同时将<match url="proxy/(.*)" />更改为<match url="^proxy/(.*)" />(额外^),这是普遍的。