WebForms自定义/动态路由

时间:2009-05-20 21:12:05

标签: asp.net webforms url-routing

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

“{any} .aspx” - 转到 - > “〜/ PageProcessor.aspx”

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

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

感谢。

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分: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文件..

希望这会有所帮助..