技术信息
AngularJS
单页应用Umbraco 7.3.0
网站,扩展为通过Umbraco.Core.ApplicationEventHandler
在单独的类库中注册路线方案
我有一个AngularJS
单页应用(SPA),我正试图通过外部PhantomJS
服务进行预渲染。
我希望MVC
的路由处理程序忽略路由/?_escaped_fragment_={fragment}
,因此request can be handled directly by ASP.NET
会传递给IIS
以代理请求。
理论
Umbraco
建立在ASP.NET MVC
。System.Web.Routing.RouteCollection
类配置。Umbraco
时,通过System.Web.Routing.RouteTable
配置的所有路由都优先于Umbraco路由,因此永远不会被Umbraco
处理** **我可能错了。据我所知,自定义路由优先于在Umbraco
路由注册之前完成。但是我不确定是否告诉MVC
忽略一条路线也会阻止Umbraco处理这条路线。
实践
我试图忽略具有以下内容的路线:
尝试一次:
routes.Ignore("?_escaped_fragment_={*pathInfo}");
这会引发错误:The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.
尝试两个:
routes.Ignore("{*escapedfragment}", new { escapedfragment = @".*\?_escaped_fragment_=\/(.*)" });
这并没有导致错误,但是Umbraco仍然接收了请求并将我的根页交给了我。 Regex validation on Regexr
问题
MVC
实际上可以忽略基于query string
?Umbraco
路由的了解是否正确?regex
是否正确?答案 0 :(得分:2)
内置路由行为不考虑查询字符串。但是,路由是可扩展的,并且可以根据需要基于查询字符串。
最简单的解决方案是创建一个可以检测查询字符串的自定义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;
}
}
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 }
);
}
}