Question

In my Global.asax file on Application_Start I create a certain number of routes in RouteTable.Routes by looping through a list of web pages collected from a database. This works fine, all routes are created and function as required. But in my web application the user can modify the database and therefore the collection of web pages. This means that during the life cycle of the application some of the routes become invalid, and new routes should be added.

What I wish to do is: The moment the user changes something to the web pages collection, I would like to clear the RouteTable and reload it by looping through the (modified) web pages collection again.

Unfortunately the Application_Start in Global.asax is ran only once, namely at the beginning of the application. I tried moving it to Session_Start which results in undesired behaviour due to the RoutesTable being static.

How do I give my user the ability to change the web page collection on-the-fly whilst having the static RouteTable remain 'in-sync' with it?

Edit

At the moment I do something like this (pseudo-code):

public class WebPageInfo      // represents a record in the database
{
 public string Title;         //  My nice page
 public string Url;           //  NicePage 
 public string PhysicalFile;  //  ~/Page.aspx
}

In Global.asax:

protected virtual void Application_Start(object sender, EventArgs e)
{
 foreach (WebPageInfo webPageInfo in webPageInfos)
 {
  RouteTable.RegisterRoute(webPageInfo.Title, webPageInfo.Url, webPageInfo.PhysicalFile);
 }
}

The problem is that during the life cycle of the application users can add/modify/delete records in the webPageInfos, how do I update the RouteTable with these changes?

Was it helpful?

Solution

The answer from usbsnowcrash is heading in the right direction. You already know how to load the RouteTable information, so rather than baking that code directly into the Application_Start method, put it into a separate method that can be called - perhaps something like RegisterRoutes. The Application_Start method would call RegisterRoutes to perform the initial load. In the code that writes the changes to the pages collection, after the updates have been committed, call RegisterRoutes to reload the RouteTable.

You'll want to include some thread-safety calls such as RouteTable.Routes.GetWriteLock() and you'll also want to clear the routes before reloading everything from the data source (as mentioned by usbsnowcrash).

I've seen this technique used with a "Bootstrapper" class that provides a static (Shared in VB) method that can be invoked as needed. The trick is to make it a method separate from the Application_Start method so that you can execute the code without relying solely on the application life cycle. Be sure to include the "clearing" calls to have things start from scratch each time the method is invoked, too.

OTHER TIPS

RouteTable can be replaced. What I would do is have some polling event that checks the DB every 10 min or so and if it detects a change then replace the routing table (make sure to make this code threadsafe). Here is what the code might look like to do the update (assuming AddAllRuleSets is a function you write to add all the rulesets from the db).

        'somewhat threadsafe
        With System.Web.Routing.RouteTable.Routes
            Using .GetWriteLock()
                routes.Clear()
                'readd routes from your db
                AddAllRulesets()
            End Using
        End With
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top