Ho molte classi di modelli che sono mappati da / a tabelle usando EF. Due di questi sono User
e UserCookie
, che sono memorizzati nelle tabelle Users
e UserCookies
.
public class User
{
public long UserId { get; set; }
public string Fullname { get; set; }
public string Email { get; set; }
(...)
}
public class UserCookie
{
public long UserCookieId { get; set; }
public long? UserId { get; set; }
public virtual User User { get; set; }
public string CookieValue { get; set; }
}
Ogni controller nella mia applicazione ASP.NET MVC è un figlio (eredita) di MyController
, che è come questo:
public class MyController : Controller
{
protected MyDbContext dbContext;
protected UserCookie userCookie;
protected User currentUser;
protected string cookieValue;
public MyController() : base()
{
this.dbContext = new MyDbContext();
this.cookieValue = "";
this.currentUser = null;
this.userCookie = null;
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
HttpCookie cookie = Request.Cookies["LoginCookie"];
if (cookie != null)
{
this.cookieValue = cookie.Value;
this.userCookie = db.UserCookies.SingleOrDefault(c => c.CookieValue.Equals(cookieValue));
if (userCookie != null)
this.currentUser = userCookie.User;
}
}
protected override ViewResult View(string viewName, string masterName, object model)
{
ViewBag.CurrentUser = currentUser;
ViewBag.UserCookie = userCookie;
ViewBag.CookieValue = cookieValue;
return base.View(viewName, masterName, model);
}
}
Quando l'utente effettua l'accesso, creo un cookie in lui con un valore casuale, come questo:
public ActionResult Login(...)
{
(...)
HttpCookie cookie = new HttpCookie("LoginCookie");
cookie.Value = Guid.NewGuid().ToString();
Response.Cookies.Add(cookie);
userCookie.User = user;
userCookie.CookieValue = cookie.Value;
db.UserCookies.Add(userCookie);
db.SaveChanges();
Il problema con tutto ciò che ho mostrato è che sto facendo una richiesta al database in ogni richiesta HTTP (cioè, in ogni chiamata a una delle mie azioni).
Inoltre non sono contento della tabella UserCookies
perché deve essere pulita e non è intuitiva. Anche Guid
generato non è sicuro.
So che quanto sbagliato è tutto questo, ma ... Non riesco a capire un modo elegante per ottenere gli stessi benefici.
Il vantaggio principale di questo è che ho accesso a currentUser
in ogni azione, quindi posso fare cose del genere facilmente:
if (!currentUser.Privileges.Any(p => p.Privilege == PrivilegesEnum.Blah))
{
(...)
}
Ho anche accesso a currentUser
in tutte le mie visualizzazioni.
Domande:
- Qual è il modo più comune per ottenere questo risultato con un vero software professionale?
- Se volessi usare la cache (come Redis), devo cambiare un sacco di cose nello scenario presentato?
- Se utilizzo la cache, dovrei memorizzare solo
userId
anziché l'intero oggetto Utente?