2009-05-20 120 views
1

我正在使用Phil Haack's WebForms的URL路由,我想定義一個「動態」的路由。比方說,我有這樣的路線:WebForms定製/動態路由

「{}任何的.aspx」 - 去 - >「〜/ PageProcessor.aspx」

這將需要這不是在PageProcessor頁面的物理頁面的任何請求。這很好。問題是,基於來自數據庫的一些數據,我需要將某些頁面路由到不同的處理器,比如說,我們可以使用DifferentPageProcessor.aspx。我無法定義捕獲所有.aspx文件的新路由,因爲第一個捕獲所有.aspx文件。

所以,我需要一種方式來處理請求之前,「路由器」決定將其送到PageProcessor並根據需要將其分叉到PageProcessor或DifferentPageProcessor。這可能嗎?

謝謝。

回答

2

我的解決方案 - 除非有人提出一個更優雅的 - 是修改WebFormRouting項目中的WebFormRouteHandler類以接受自定義謂詞。

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

當然lambda表達式應該查找從別的地方(數據庫或緩存)的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文件..

希望這有助於..