Ciao Filippo,
cerca di mettere tutte le proprietà in un solo oggetto, così sarà più facile da gestire. Per esempio creati una classe chiamata UserProfile tipo questa, che contenga tutte le proprietà di cui hai bisogno.
public class UserProfile
{
public string Email { get; set; }
public string Nome { get; set; }
public string Indirizzo { get; set; }
}
Il piano è il seguente: se in una variabile di sessione come Session["UserProfile"] esiste già un'istanza di quella classe, allora la usiamo. Altrimenti, bisognerà interrogare il database per costruirla e poi la potremo assegnare alla stessa variabile di Sessione affinché sia disponibile in tutte le successive richieste.
E' semplice da fare ma l'obiettivo è quello di non avere questa logica tra i piedi in tutti i punti in cui ti serve accedere a quei dati.
Sarebbe bello se si potesse "ricevere" l'istanza di UserProfile come parametro di un'action, in modo che sia subito pronto da usare. Per esempio:
public ActionResult Index(UserProfile userProfile) {
//Fai qualcosa con userProfile
}
Questo è possibile se ti scrivi un model binder personalizzato tipo il seguente:
public class UserProfileModelBinder : System.Web.Mvc.IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
//Mi assicuro che il tipo da risolvere sia UserProfile, ovvero la mia classe
//in cui si trovano indirizzo, città, ecc...
if (bindingContext.ModelType != typeof(UserProfile))
return null;
var identity = controllerContext.HttpContext.User.Identity;
//Se l'utente è anonimo non posso ottenere il suo profilo
if (!identity.IsAuthenticated)
return null;
//Vado a controllare se il profilo per caso è già stato cachato in sessione
var session = controllerContext.HttpContext.Session;
var userProfile = session["UserProfile"] as UserProfile;
if (userProfile == null)
{
//Altrimenti lo vado a prendere dal db
//Usando lo username come criterio
var username = identity.Name;
//Qui faccio la query al db
var userProfileEstrattoDalDatabase = ...;
// e poi lo mappo (o lo assegno) alla variabile userProfile
userProfile = userProfileEstrattoDalDatabase;
// lo assegno anche alla variabile di sessione, così che sarà disponibile alla prossima richiesta
session["UserProfile"] = userProfile;
}
//Lo restituisco
return userProfile;
}
}
Non resta che registrarlo nel global.asax, all'interno del metodo Application_Start
System.Web.Mvc.ModelBinders.Binders.Add(typeof(UserProfile), new UserProfileModelBinder());
Ci sono ovviamente anche altri sistemi per ottenere il profilo dell'utente. Alcuni non sono neanche basati sulla sessione. Per esempio è possibile inserire le informazioni dell'utente (cifrate) direttamente all'interno del cookie di autenticazione (vengono chiamate
claims), purché non siano troppe altrimenti il cookie comincia ad avere un certo peso.
Tu che meccanismo di autenticazione usi? ASP.NET Identity?
ciao,
Moreno
Modificato da BrightSoul il 21 agosto 2016 19.13 -