简体   繁体   English

MVC IgnoreRoute /?_ escaped_fragment_ =继续使用IIS ARR进行反向代理

[英]MVC IgnoreRoute /?_escaped_fragment_= to continue Reverse Proxy with IIS ARR

Technical Information 技术信息

Scenario 情境

I have an AngularJS single page app (SPA) that I'm trying to pre-render via an external PhantomJS service. 我有一个AngularJS单页应用程序(SPA),我正在尝试通过外部PhantomJS服务进行预渲染。

I want MVC 's route handler to ignore the route /?_escaped_fragment_={fragment} , so the request can be handled directly by ASP.NET and thus passed on to IIS to proxy the request. 我希望MVC的路由处理程序忽略路由/?_escaped_fragment_={fragment} ,因此该请求可以由ASP.NET直接处理 ,然后传递给IIS以代理该请求。

In Theory 理论上

**I could be wrong. **我可能是错的。 As far as I'm aware, custom routing takes precedence as it's done before the Umbraco routes are registered. 据我所知,自定义路由的优先级就像注册Umbraco路由之前所做的那样。 However I'm unsure whether telling MVC to ignore a route would also prevent Umbraco from handling that route. 但是我不确定告诉MVC忽略路由是否还会阻止Umbraco处理该路由。

In Practise 实践中

I have attempted to ignore the routes with the following: 我尝试使用以下命令忽略路由:

Attempt one: 尝试之一:

routes.Ignore("?_escaped_fragment_={*pathInfo}");

This throws an error: The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character. 这将引发错误: The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character. The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.

Attempt two: 尝试两次:

routes.Ignore("{*escapedfragment}", new { escapedfragment = @".*\?_escaped_fragment_=\/(.*)" });

This didn't result in an error, however Umbraco still picked up the request and handed me back my root page. 这并没有导致错误,但是Umbraco仍然收到了请求并将我递回了我的根页面。 Regex validation on Regexr . Regexr上的正则表达式验证

Questions 问题

  • Can MVC actually ignore a route based on its query string ? MVC可以根据其query string实际忽略路由吗?
  • Is my knowledge of Umbraco 's routing correct? 我对Umbraco的路线了解是否正确?
  • Is my regex correct? 我的regex正确吗?
  • Or am I missing something? 还是我错过了什么?

The built-in routing behavior doesn't take the query string into consideration. 内置的路由行为不考虑查询字符串。 However, routing is extensible and can be based on query string if needed. 但是,路由是可扩展的,并且可以根据需要基于查询字符串。

The simplest solution is to make a custom RouteBase subclass that can detect your query string, and then use the StopRoutingHandler to ensure the route doesn't function. 最简单的解决方案是创建一个自定义RouteBase子类,该子类可以检测您的查询字符串,然后使用StopRoutingHandler确保路由不起作用。

public class IgnoreQueryStringKeyRoute : RouteBase
{
    private readonly string queryStringKey;

    public IgnoreQueryStringKeyRoute(string queryStringKey)
    {
        if (string.IsNullOrWhiteSpace(queryStringKey))
            throw new ArgumentNullException("queryStringKey is required");
        this.queryStringKey = queryStringKey;
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        if (httpContext.Request.QueryString.AllKeys.Any(x => x == queryStringKey))
        {
            return new RouteData(this, new StopRoutingHandler());
        }

        // Tell MVC this route did not match
        return null;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        // Tell MVC this route did not match
        return null;
    }
}

Usage 用法

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // This route should go first
        routes.Add(
            name: "IgnoreQuery",
            item: new IgnoreQueryStringKeyRoute("_escaped_fragment_"));


        // Any other routes should be registered after...

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM