WebForms пользовательская / динамическая маршрутизация - PullRequest
1 голос
/ 21 мая 2009

Я использую Фил Хаак маршрутизация URL для веб-форм, и я хотел бы определить маршрут, который является "динамическим". Допустим, у меня есть этот маршрут:

"{any} .aspx" - идет к -> "~ / PageProcessor.aspx"

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

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

Спасибо.

Ответы [ 2 ]

2 голосов
/ 21 мая 2009

Мое решение - если кто-то не придумает более элегантного - было изменить класс 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 голосов
/ 04 июня 2010

Это в 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, который содержит настройки моих приложений. можно загрузить как стандартную страницу.

Важный бит: метод BuildManager.CreateInstanceFromVirtualPath, который загружает любой aspx-файл, на который вы указываете.

Надеюсь, это поможет ..

...