WebForms custom / dynamic routing

I’m using Phil Haack’s URL routing for WebForms and I would like to define a route that’s “dynamic.” Let’s say I have this route:

“{any}.aspx” — goes to –> “~/PageProcessor.aspx”

This would take any request that’s not a physical page to the PageProcessor page. This works great. The problem is that, based on some data that comes from a database, I need certain pages to be routed to a different processor, let’s say DifferentPageProcessor.aspx. I can’t define a new route that catches all the .aspx files because the first one catches everything.

So, I would need a way to process the request before the “router” decides to take it to PageProcessor and fork it to either PageProcessor or DifferentPageProcessor as needed. Is this possible?

Thanks.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

My solution — unless somebody comes up with a more elegant one — was to modify the WebFormRouteHandler class in the WebFormRouting project to accept a custom predicate.

public WebFormRouteHandler(string virtualPath, bool checkPhysicalUrlAccess, Func<RequestContext, string> custom)

Then inside the class I would store the custom parameter into private CustomVirtualPath property. To use it, I had to change GetSubstitutedVirtualPath to this:

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

For the project to compile we need to change WebFormRoute and WebFormRouteExtensions to allow the passing of the custom parameter down the chain. When all done I can write this in global.asax.cs

routes.MapWebFormRoute("All", "{any}.aspx", "~/", false,
                         context =>
                           {
                             return ((string)context.RouteData.Values["any"] == "test"
                                       ? "~/PageProcessor.aspx"
                                       : "~/DifferentPageProcessor.aspx");
                           });

Of course the body of the lambda expression should look up the URL from some other place (database or cache).

Method 2

It’s in VB but this is how I do it:

 Routes.Add("Root", New Route("{*URLRequest}", New myRootRouteHandler()))

This does the same as yours, it catches the entire request but it then passes it off to my own custom route handler class:

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

In my example I have overloaded System.ui.page so that every aspx page in my project can inherit certain properties automatically like for example the mySettings object which contains my apps settings.. This is why I dim page as myCustom_Page_Base, you can load it as a standard page.

The important bit is: BuildManager.CreateInstanceFromVirtualPath method this will load whatever aspx file you point to it..

Hope this helps..


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x