1

我正在为 WebForms 使用Phil Haack 的URL 路由,我想定义一个“动态”的路由。假设我有这条路线:

"{any}.aspx" -- 转到 --> "~/PageProcessor.aspx"

这会将任何不是物理页面的请求带到 PageProcessor 页面。这很好用。问题是,基于来自数据库的一些数据,我需要将某些页面路由到不同的处理器,比如 DifferentPageProcessor.aspx。我无法定义捕获所有 .aspx 文件的新路由,因为第一个路由会捕获所有文件。

因此,在“路由器”决定将请​​求带到 PageProcessor 并根据需要将其分叉到 PageProcessor 或 DifferentPageProcessor 之前,我需要一种方法来处理请求。这可能吗?

谢谢。

4

2 回答 2

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。

于 2009-05-20T21:58:42.747 回答
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 文件。

希望这可以帮助..

于 2010-06-04T08:37:04.893 回答