2009-05-20 159 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文件..

希望这有助于..