web-dev-qa-db-fra.com

ASP.NET MVC 5 - Identité. Comment obtenir l'ApplicationUser actuel

J'ai une entité Article dans mon projet qui a la propriété ApplicationUser nommée Author. Comment obtenir l'objet complet de ApplicationUser actuellement enregistré? Lors de la création d'un nouvel article, je dois définir la propriété Author dans Article sur la ApplicationUser actuelle.

Dans l'ancien mécanisme d'adhésion, c'était simple, mais dans la nouvelle approche de l'identité, je ne sais pas comment faire cela.

J'ai essayé de le faire de cette façon:

  • Ajout de l'instruction using pour les extensions d'identité: using Microsoft.AspNet.Identity;
  • Ensuite, j'essaie d'obtenir l'utilisateur actuel: ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == User.Identity.GetUserId());

Mais j'obtiens l'exception suivante:

LINQ to Entities ne reconnaît pas la méthode 'System.String GetUserId (System.Security.Principal.IIdentity)' et ne peut pas être traduite dans une expression de magasin . Source = EntityFramework

221
Ellbar

Vous n'avez pas besoin d'interroger directement la base de données pour ApplicationUser actuel.

Cela introduit une nouvelle dépendance consistant à avoir un contexte supplémentaire pour les débutants, mais les tables de la base de données des utilisateurs changent (3 fois au cours des 2 dernières années), mais l'API est cohérente. Par exemple, la table users est maintenant appelée AspNetUsers dans Identity Framework et les noms de plusieurs champs de clé primaire ne cessant de changer, le code de plusieurs réponses ne fonctionnera plus as-is.

Un autre problème est que l'accès OWIN sous-jacent à la base de données utilisera un contexte séparé. Par conséquent, des modifications apportées depuis un accès SQL distinct peuvent produire des résultats non valides (par exemple, ne pas voir les modifications apportées à la base de données). Encore une fois, la solution consiste à travailler avec l'API fournie et de ne pas essayer de contourner.

La manière correcte d'accéder à l'objet utilisateur actuel dans l'identité ASP.Net (à cette date) est la suivante:

var user = UserManager.FindById(User.Identity.GetUserId());

ou, si vous avez une action asynchrone, quelque chose comme:

var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());

FindById nécessite que vous disposiez de l'instruction using suivante pour que les méthodes UserManager non asynchrones soient disponibles (il s'agit des méthodes extension pour UserManager, donc si vous n'incluez pas cela, vous ne verrez que FindByIdAsync):

using Microsoft.AspNet.Identity;

Si vous ne vous trouvez pas du tout dans un contrôleur (par exemple, vous utilisez une injection IOC), l'identifiant de l'utilisateur est alors récupéré dans son intégralité à partir de:

System.Web.HttpContext.Current.User.Identity.GetUserId();

Si vous ne vous trouvez pas dans le contrôleur de compte standard, vous devrez ajouter ce qui suit (à titre d'exemple) à votre contrôleur:

1. Ajoutez ces deux propriétés:

    /// <summary>
    /// Application DB context
    /// </summary>
    protected ApplicationDbContext ApplicationDbContext { get; set; }

    /// <summary>
    /// User manager - attached to application DB context
    /// </summary>
    protected UserManager<ApplicationUser> UserManager { get; set; }

2. Ajoutez ceci dans le constructeur du contrôleur:

    this.ApplicationDbContext = new ApplicationDbContext();
    this.UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(this.ApplicationDbContext));

Mise à jour mars 2015

Remarque: La dernière mise à jour d'Identity Framework modifie l'une des classes sous-jacentes utilisées pour l'authentification. Vous pouvez maintenant y accéder à partir du contexte Owin du contenu HTTP actuel.

ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());

Addenda:

Lorsque vous utilisez EF et Identity Framework avec Azure, via une connexion à une base de données distante (par exemple, test de l'hôte local vers une base de données Azure), vous pouvez utiliser de manière aléatoire l'erreur redoutée «erreur: 19 - La connexion physique n'est pas utilisable». Comme la cause est cachée dans Identity Framework, où vous ne pouvez pas ajouter de tentatives (ou ce qui semble être un .Include(x->someTable) manquant), vous devez implémenter une SqlAzureExecutionStrategy personnalisée dans votre projet.

416
Gone Coding

Mon erreur, je n'aurais pas dû utiliser une méthode dans une requête LINQ.

Code correct:

string currentUserId = User.Identity.GetUserId();
ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);
55
Ellbar

C'est dans les commentaires des réponses mais personne n'a posté ceci comme solution réelle.

Vous devez juste ajouter une instruction using en haut:

using Microsoft.AspNet.Identity;
29
rtpHarry

Le code de Ellbar fonctionne! Vous avez seulement besoin d'ajouter en utilisant.

1 - using Microsoft.AspNet.Identity;

Et ... le code d'Ellbar:

2 - string currentUserId = User.Identity.GetUserId(); ApplicationUser currentUser = db.Users.FirstOrDefault(x => x.Id == currentUserId);

Avec ce code (dans currentUser), vous travaillez les données générales de l'utilisateur connecté, si vous voulez des données supplémentaires ... voir ce lien

9
Diego Borges

Depuis ASP.NET Identity 3.0.0, cela a été refactoré dans

//returns the userid claim value if present, otherwise returns null
User.GetUserId();
6
Seth IK
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
ApplicationUser currentUser = UserManager.FindById(User.Identity.GetUserId());

string ID = currentUser.Id;
string Email = currentUser.Email;
string Username = currentUser.UserName;
5
Majid joghataey

À l’heure actuelle, le modèle de projet asp.mvc crée un contrôleur de compte qui obtient le gestionnaire de mémoire utilisateur de cette façon:

HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>()

Ce qui suit fonctionne pour moi:

ApplicationUser user = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(User.Identity.GetUserId());
3
Holger Thiemann

Pour MVC 5, il suffit de regarder à l'intérieur de la méthode EnableTwoFactorAuthentication de ManageController dans l'échafaud de gabarit WebApplication.

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> EnableTwoFactorAuthentication()
        {
            await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true);
            var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
            if (user != null)
            {
                await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
            }
            return RedirectToAction("Index", "Manage");
        }

La réponse est là, comme suggéré par Microsoft lui-même:

var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());

Il aura toutes les propriétés supplémentaires que vous avez définies dans la classe ApplicationUser.

1
Paceman

Si quelqu'un travaille avec Identity utilisateurs dans web forms, je le fais fonctionner de la manière suivante:

var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var user = manager.FindById(User.Identity.GetUserId());
0
Jamshaid Kamran

J'étais avec succès disponible pour obtenir l'application utilisateur en suivant morceau de code

var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
            var user = manager.FindById(User.Identity.GetUserId());
            ApplicationUser EmpUser = user;
0
Abdul Hannan