Come ricaricare RouteTable quando è cambiata la raccolta di pagine Web?
-
29-10-2019 - |
Domanda
Nel mio Global.asax
file su Application_Start
Creo un certo numero di percorsi in RouteTable.Routes
Attraversando un elenco di pagine Web raccolte da un database. Funziona bene, tutti i percorsi sono creati e funzionano come richiesto. Ma nella mia applicazione Web l'utente può modificare il database e quindi la raccolta di pagine Web. Ciò significa che durante il ciclo di vita dell'applicazione alcune delle rotte diventano non valide e si dovrebbero aggiungere nuove rotte.
Quello che desidero fare è: nel momento in cui l'utente cambia qualcosa nella raccolta delle pagine Web, vorrei cancellare il route e ricaricarlo, loopando di nuovo attraverso la raccolta (modificata).
Purtroppo il Application_Start
in Global.asax
è eseguito solo una volta, vale a dire all'inizio dell'applicazione. Ho provato a spostarlo in Session_Start
che si traduce in comportamenti indesiderati a causa del RoutesTable
essere statico.
Come faccio a dare al mio utente la possibilità di modificare la raccolta di pagine Web al volo RouteTable
rimanere "in sintonia" con esso?
Modificare
Al momento faccio qualcosa del genere (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);
}
}
Il problema è che durante il ciclo di vita degli utenti dell'applicazione possono aggiungere/modificare/eliminare i record nei webPageInfos
, Come si aggiorna il routetable con queste modifiche?
Soluzione
La risposta da USBSNOWCRASH sta andando nella giusta direzione. Sai già come caricare il RouteTable
informazioni, quindi piuttosto che cuocere quel codice direttamente in Application_Start
metodo, mettilo in un metodo separato che può essere chiamato - forse qualcosa di simile RegisterRoutes
. Il Application_Start
Il metodo chiamerebbe RegisterRoutes
Per eseguire il carico iniziale. Nel codice che scrive le modifiche alla raccolta delle pagine, dopo che gli aggiornamenti sono stati commessi, chiama RegisterRoutes
Per ricaricare la route.
Ti consigliamo di includere alcune chiamate di sicurezza thread come RouteTable.Routes.GetWriteLock()
E ti consigliamo anche di cancellare i percorsi prima di ricaricare tutto dall'origine dati (come menzionato da USBSNOWCRASH).
Ho visto questa tecnica usata con una classe "bootstrapper" che fornisce un static
(Shared
nel metodo VB) che può essere invocato secondo necessità. Il trucco è renderlo un metodo separato da Application_Start
Metodo in modo da poter eseguire il codice senza fare affidamento esclusivamente sul ciclo di vita dell'applicazione. Assicurati di includere le chiamate di "cancellazione" per far iniziare le cose ogni volta che viene invocato anche il metodo.
Altri suggerimenti
RouteTable può essere sostituito. Quello che farei è avere un evento di polling che controlla il DB ogni 10 minuti circa e se rileva una modifica, sostituisci la tabella di routing (assicurati di rendere questo codice threadSafe). Ecco come potrebbe essere il codice fare l'aggiornamento (supponendo che AddallRuleset sia una funzione che scrivi per aggiungere tutte le regole del DB).
'somewhat threadsafe
With System.Web.Routing.RouteTable.Routes
Using .GetWriteLock()
routes.Clear()
'readd routes from your db
AddAllRulesets()
End Using
End With