在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?
答案 0 :(得分:6)
usbsnowcrash 的答案朝着正确的方向发展。您已经知道如何加载RouteTable
信息,因此,不要将该代码直接烘焙到Application_Start
方法中,而是将其放入可以调用的单独方法中 - 可能类似于RegisterRoutes
。 Application_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