Est-ce de l'entité Personnalisée dans la Base de Contrôleur ASP.NET MVC 3 terriblement inefficace?
Malgré le fait que j'ai été ici pendant un certain temps, c'est ma première question, de sorte s'il vous plaît être gentil avec moi.
Je suis en utilisant ASP.NET MVC 3
et je veux créer un personnalisé Principal
donc je peux stocker un peu plus d'infos sur l'utilisateur courant que ce qui est standard, donc pas besoin d'aller à la base de données trop souvent. C'est assez standard des trucs que je suis après. Disons simplement un e-mail l'adresse et le nom d'utilisateur dans la première instance.
J'ai décidé de ranger l'objet dans le cache que je suis conscient qu'il n'est pas conseillé de le stocker dans la session.
Je ne veux pas avoir à faire un moulage de la User
objet, donc j'ai voulu remplacer la User
objet dans le contrôleur. Si je peux juste aller User.UserId
et sont garantis de quelque chose.
J'ai donc créé une entité personnalisée comme ceci:
public class MyPrincipal : IPrincipal
{
public MyPrincipal(IIdentity ident, List<string> roles, string email, Guid userId)
{
this._identity = ident;
this._roles = roles;
this._email = email;
this._userId = userId;
}
IIdentity _identity;
public IIdentity Identity
{
get { return _identity; }
}
private List<string> _roles;
public bool IsInRole(string role)
{
return _roles.Contains(role);
}
private string _email;
public string Email
{
get { return _email; }
}
private Guid _userId;
public Guid UserId
{
get { return _userId; }
}
}
Et j'ai un Contrôleur de Base comme ceci:
public class BaseController : Controller
{
protected virtual new MyPrincipal User
{
get
{
if (base.User is MyPrincipal)
{
return base.User as MyPrincipal;
}
else
{
return new MyPrincipal(base.User.Identity, new List<string>(0), "", Guid.Empty );
}
}
}
protected override void OnAuthorization(AuthorizationContext filterContext)
{
if (User != null)
{
if (User.Identity.IsAuthenticated)
{
if (User.Identity is FormsIdentity)
{
FormsIdentity id = base.User.Identity as FormsIdentity;
MyPrincipal principal = (MyPrincipal)filterContext.HttpContext.Cache.Get(id.Name);
if (principal == null)
{
MembershipUser user = Membership.GetUser();
//Create and populate your Principal object with the needed data and Roles.
principal = new MyPrincipal(id, Roles.GetRolesForUser(id.Name).ToList(), user.Email, (Guid)user.ProviderUserKey);
filterContext.HttpContext.Cache.Add(
id.Name,
principal,
null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
new System.TimeSpan(0, 30, 0),
System.Web.Caching.CacheItemPriority.Default,
null);
}
filterContext.HttpContext.User = principal;
System.Threading.Thread.CurrentPrincipal = principal;
base.OnAuthorization(filterContext);
}
}
}
}
}
Si vous avez un coup d'oeil vous allez vite réaliser que si l'utilisateur n'est pas connecté alors tout appel à la User
objet avez à courir à travers ce morceau de code:
return new MyPrincipal(base.User.Identity, new List<string>(0), "", Guid.Empty );
et cela se sent terriblement inefficace pour moi, même si c'est seulement à la création d'objets vides pour le manque des trucs.
Il fonctionne très bien.
Donc je suppose que je veux savoir si c'est réellement bon et que je devrais arrêter d'être si anale sur les performances et l'efficacité, ou si mes craintes sont corrects, dans ce cas que dois-je faire à la place? [Merci de ne pas dire "faire une vie, mate!"]
+1 une Belle. Non, je n'ai pas. Mais le truc c'est que je me sentais assez intelligent pour avoir fait tout le travail jusqu'à ce que j'ai regardé le méchant ligne de code! Wow! Je suis vraiment anal! Je suppose que c'est ce que vient d'avoir commencé à coder sur la BBC Micro, où les cycles d'horloge ont été peu nombreuses et espacées...
OriginalL'auteur Tom Chantler | 2011-11-25
Vous devez vous connecter pour publier un commentaire.
Pas - il n'y a rien de spécifiquement de mal avec ce code de rendement, d'un point de vue qui se démarque. BEAUCOUP d'objets de la création sur l'extrémité arrière dans ASP.NET, votre unique objet est d'une goutte dans le seau. Depuis l'instanciation de classe est extrêmement rapide, je ne serais pas inquiète.
Pourquoi êtes-vous en ignorant les séances ici? Les informations de Session n'a pas de date d'expiration, donc il n'y a pas de vérification supplémentaire derrière la scène. Sauf si vous êtes en utilisant un proc serveur de session, il n'y a pas de sérialisation de l'objet (aucun avec le cache).
Le cache est pour tous les utilisateurs si vous avez droit à une chance (même légère) d'un code d'erreur de retourner le mal principal où un cache par utilisateur - ne pas courir le risque de.
Si vous voulez que cette disposition pour toutes les demandes (pas juste MVC), je voudrais envisager de mettre cela dans Application_PostAuthenticateRequest
Application_PostAuthenticateRequest
que je pense que le code n'allait fonctionner pour les demandes de choses comme les css, images, javascript, etc alors qu'avec mon code il ne sera pas. Est ce que le droit? Toutes les images ont besoin d'être protégés sont servis par MVCFileContentResult
méthodes et sont donc encore couvert.OriginalL'auteur Adam Tuliper - MSFT
Ce poste peut être d'utilisation. Notez l'utilisation des données de l'utilisateur dans le ticket d'authentification.
ASP.NET MVC - Ensemble personnalisé de l'Identité ou de IPrincipal
OriginalL'auteur Darthg8r