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:
using Microsoft.AspNet.Identity;
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
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:
/// <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; }
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());
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.
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);
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;
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
Depuis ASP.NET Identity 3.0.0, cela a été refactoré dans
//returns the userid claim value if present, otherwise returns null
User.GetUserId();
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;
À 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());
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.
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());
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;