2009-05-20 5 views
1

Я использую Phil Haack's URL-адрес маршрутизации для WebForms, и я бы хотел определить маршрут, который является «динамическим». Скажем, у меня есть этот маршрут:WebForms пользовательская/динамическая маршрутизация

«{любой} .aspx» - идет в -> «~/PageProcessor.aspx»

Это будет принимать любой запрос, что это не физическая страница на страницу PageProcessor , Это отлично работает. Проблема в том, что на основе некоторых данных, поступающих из базы данных, мне нужно, чтобы некоторые страницы были перенаправлены на другой процессор, скажем, на другойPageProcessor.aspx. Я не могу определить новый маршрут, который ловит все .aspx-файлы, потому что первый ловит все.

Итак, мне понадобится способ обработки запроса до того, как «маршрутизатор» решит перенести его в PageProcessor и переделать его на любой PageProcessor или DifferentPageProcessor по мере необходимости. Это возможно?

Спасибо.

ответ

2

Мое решение - если только кто-то не придумал более элегантный вариант - это изменить класс 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 из другого места (базы данных или кэш).

0

Это в VB, но это, как я это делаю:

Routes.Add("Root", New Route("{*URLRequest}", New myRootRouteHandler())) 

Это делает то же самое, как ваша, она захватывала весь запрос, но затем передает его в мой собственный класс обработчика маршрута:

Imports System.Web.Routing 
Imports System.Security 
Imports System.Web.Compilation 
Imports System.Web 

Public Class myRootRouteHandler 
    Implements IRouteHandler 
    Implements IRequiresSessionState 

    Private Path As String 

    Public Function GetHttpHandler(ByVal requestContext As RequestContext) As IHttpHandler Implements IRouteHandler.GetHttpHandler 
    Dim url As String = Web.HttpContext.Current.Request.ServerVariables("SERVER_NAME") 
    Dim Key As String = requestContext.RouteData.Values("URLRequest") 
    Dim myConfig As New LoadMyConfig(url) 
    Dim aspxToLoad As String = myConfig.getPageVirtualPath(Key) 
    Dim page As myCustom_Page_Base = TryCast(BuildManager.CreateInstanceFromVirtualPath(aspxToLoad, GetType(myCustom_Page_Base)), myCustom_Page_Base) 

    page.RequestContext = requestContext 
    page.strRequestContext = Key 
    page.mySettings = myConfig 

    Return page 

End Function 

в моем примере я перегружен System.ui.page так, что каждая страница ASPX в моем проекте может наследовать некоторые свойства автоматически, как, например, объект, на который MySettings, который содержит настройки моих приложений .. Вот почему я тусклая страницу как myCustom_Page_Base , вы можете загрузить его как стандартную страницу.

Важные бит Метод BuildManager.CreateInstanceFromVirtualPath это будет загружать любой файл ASPX вы указать на него ..

Надеется, что это помогает ..