如何在网页集合发生变化时重新加载RouteTable?

时间:2011-02-05 08:04:15

标签: c# asp.net global-asax routetable

Global.asax上的Application_Start文件中,我通过循环浏览从数据库收集的网页列表,在RouteTable.Routes中创建了一定数量的路由。这很好,所有路线都是根据需要创建和运行的。但是在我的Web应用程序中,用户可以修改数据库,从而修改网页集合。这意味着在应用程序的生命周期中,某些路由将变为无效,并且应添加新路由。

我希望做的是:当用户将某些内容更改为网页集时,我想清除RouteTable并通过再次循环遍历(修改过的)网页集来重新加载它。

不幸的是Application_Start中的Global.asax只运行一次,即在应用程序的开头。我尝试将其移至Session_Start,由于RoutesTable是静态的,导致意外行为。

如何让我的用户能够动态更改网页集,同时让静态RouteTable保持“同步”状态?

修改

目前我做这样的事情(伪代码):

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

在Global.asax中:

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

问题是在应用程序的生命周期中,用户可以在webPageInfos中添加/修改/删除记录,如何使用这些更改更新RouteTable?

2 个答案:

答案 0 :(得分:6)

usbsnowcrash 的答案朝着正确的方向发展。您已经知道如何加载RouteTable信息,因此,不要将该代码直接烘焙到Application_Start方法中,而是将其放入可以调用的单独方法中 - 可能类似于RegisterRoutesApplication_Start方法会调用RegisterRoutes来执行初始加载。在将更改写入pages集合的代码中,在提交更新后,调用RegisterRoutes重新加载RouteTable。

您需要包含一些线程安全调用,例如RouteTable.Routes.GetWriteLock(),并且您还需要在从数据源重新加载所有内容之前清除路由(如 usbsnowcrash 所述) )。

我已经看到这种技术与“Bootstrapper”类一起使用,该类提供了static(VB中的Shared)方法,可以根据需要调用该方法。诀窍是使它成为一个独立于Application_Start方法的方法,这样您就可以执行代码而不必仅依赖于应用程序生命周期。确保包含“清除”调用,以便每次调用方法时都从​​头开始。

答案 1 :(得分:2)

可以替换RouteTable。我要做的是有一些轮询事件,每10分钟左右检查一次数据库,如果检测到更改,则替换路由表(确保使此代码线程安全)。以下是执行更新的代码(假设AddAllRuleSets是您编写的函数,用于添加数据库中的所有规则集)。

        'somewhat threadsafe
        With System.Web.Routing.RouteTable.Routes
            Using .GetWriteLock()
                routes.Clear()
                'readd routes from your db
                AddAllRulesets()
            End Using
        End With