2011-02-09 1 views
9

Sono voler memorizzare nella cache i ruoli di un utente è in per ogni richiesta che viene in Ci sono molti posti in tutto ogni pagina dove dove abbiamo qualcosa di simile:Per-Richiesta dati statici in ASP.NET

<% if(Roles.IsUserInRole("RoleName")) {%> 
    <!-- Conditional Rendering --> 
<% } else if(Roles.IsUserInRole("AnotherRole") {%> 
    <!-- You get the point --> 
<% } %> 

Poiché questo è tutto memorizzato in un database SQL, ognuna di queste richieste colpisce il database. So che ci sono modi per memorizzare nella cache i ruoli in un cookie, ma non voglio farlo. Ad ogni modo, quello che stavo pensando era qualcosa del genere.

public static class SecurityUtils 
    { 
     public static string[] UserRoles() 
     { 
      var context = HttpContext.Current; 

      if (context == null) return Enumerable.Empty<string>(); 

      string[] roles; 

      roles = context.Items["UserRoles"] as string[]; 

      if (roles == null) 
      { 
       roles = Roles.GetRolesForUser(); 
       context.Items["UserRoles"] = roles; 
      } 

      return roles; 
     } 
    } 

Chiunque veda eventuali problemi con questo? So che chiamare sempre a UserRoles() cercherà l'oggetto nel contesto e forse questa non è la cosa più efficace da fare. Quello che voglio davvero sapere è se questo verrà memorizzato nella cache in base alle richieste, in modo che non vi siano sovrapposizioni con le richieste degli altri utenti.

+0

Hai un manzo con 'Sessione'? – bzlm

+0

@bzlm - forse i ruoli non sono "Serializzabili"? – Oded

+3

@Oded Hai ragione. Forse 'stringa []' nell'esempio di codice nella domanda si riferisce ad arcobaleni e unicorni piuttosto che a sequenze di lettere e numeri. – bzlm

risposta

11

Sembra abbastanza sicuro a una rapida occhiata. HttpContext.Current.Items è una cache di richieste per HTTP. Un'altra opzione da considerare per ridurre ulteriormente le chiamate al database sarebbe quella di utilizzare lo stato della sessione.

Si consideri uno scenario in cui si dispone di una pagina con un sacco di cose ajax in corso. Ogni richiesta Ajax invocherà una chiamata al database per caricare i ruoli di sicurezza, poiché sono tutte richieste HTTP separate.

+0

Questo è un grande punto sulle richieste di Ajax e così via. Probabilmente userò la sessione, ma assicurati che venga cancellato se l'utente aggiunge o cambia ruoli. – Micah

+0

Sottolineerò un avvertimento probabilmente ovvio sull'utilizzo di una sessione per ridurre le chiamate al database: è possibile configurare il provider di sessione effettivo come database o server esterno (come Redis, AWS DynamoDb), quindi prestare attenzione a come è l'ambiente impostare. – drzaus

+0

So che questo è vecchio, ma credo che intendessi 'HttpContext' invece di' HttpContent' – Davy8

3

Lo memorizzerà nella cache per richiesta, poiché si sta utilizzando l'attuale HttpContext.

Se si stava utilizzando un membro statico, sarebbe stato memorizzato nella cache fino a quando l'applicazione Web non fosse stata riciclata.

Come tale, sembra buono - un modello abbastanza comune in effetti (utilizzando un membro statico come cache in memoria o l'attuale HttpContext).

+1

@Oded: Puoi spiegare questo: * Questo verrà memorizzato nella cache fino a quando l'applicazione Web non verrà riciclata. *? –

+0

La mia comprensione è che HttpContext.Items è una cache per richiesta, non è così? Cioè http://www.4guysfromrolla.com/articles/060904-1.aspx –

+0

@Ladislav Mrnka - C'è una quantità predefinita di tempo prima che un'applicazione Web .NET si reimposti da sola. Intendo fino a quando non viene ripristinato, manualmente o automaticamente. – Oded