Мое решение - если кто-то не придумает более элегантного - было изменить класс WebFormRouteHandler в проекте WebFormRouting для принятия собственного предиката.
public WebFormRouteHandler(string virtualPath, bool checkPhysicalUrlAccess, Func<RequestContext, string> custom)
Тогда внутри класса я сохраню пользовательский параметр в частном свойстве CustomVirtualPath. Чтобы использовать его, мне пришлось изменить GetSubstitutedVirtualPath на это:
public string GetSubstitutedVirtualPath(RequestContext requestContext)
{
string path = VirtualPath;
if (CustomVirtualPath != null)
{
path = CustomVirtualPath(requestContext);
}
if (!path.Contains("{")) return path;
//Trim off ~/
string virtualPath = path.Substring(2);
Route route = new Route(virtualPath, this);
VirtualPathData vpd = route.GetVirtualPath(requestContext, requestContext.RouteData.Values);
if (vpd == null) return path;
return "~/" + vpd.VirtualPath;
}
Для компиляции проекта нам нужно изменить WebFormRoute и WebFormRouteExtensions, чтобы разрешить передачу пользовательского параметра по цепочке. Когда все сделано, я могу написать это в global.asax.cs
routes.MapWebFormRoute("All", "{any}.aspx", "~/", false,
context =>
{
return ((string)context.RouteData.Values["any"] == "test"
? "~/PageProcessor.aspx"
: "~/DifferentPageProcessor.aspx");
});
Конечно, тело лямбда-выражения должно искать URL-адрес из какого-то другого места (базы данных или кэша).