J'ai quelques tables qui ont un ID utilisateur uniqueidentifier qui se rapporte à aspnet_Users.UserID. Lorsque l'utilisateur soumet des données pour ces tables, puisque la méthode du contrôleur a un [Autoriser], j'obtiens un objet Utilisateur. Je peux obtenir le nom d'utilisateur avec User.Identity.Name, mais comment puis-je obtenir l'ID utilisateur pour pouvoir établir (la propriété) la relation?
Il semble que vous ne puissiez pas l'obtenir à partir de l'objet User, mais vous pouvez l'obtenir de cette façon:
Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey;
Voici la solution:
Comprendre:
using Microsoft.AspNet.Identity;
Utilisez ensuite des méthodes d'extension:
User.Identity.GetUserId();
Premièrement, cette réponse n'est pas strictement une réponse MVC, mais une réponse ASP.NET. Le fait que votre site soit MVC n'est pas pertinent pour résoudre le problème, dans ce cas.
Hmm. Je ne suis pas très sûr de la façon dont vous gérez vos utilisateurs dans votre système, mais il semble que vous utilisiez le (très mauvais) asp.net membership provider
qui sort de la boîte avec .net. Ceci est laissé entendre par le fait que vous avez dit
Avec le système d'authentification par défaut des formulaires, qui utilise la valeur par défaut FormsIdentity , il n'a qu'une seule propriété appelée Name (comme vous l'avez correctement noté). Cela signifie qu'il n'a qu'une seule valeur où placer des informations utilisateur uniques. Dans votre cas, vous mettez Name/UserName/DisplayName , dans la propriété Name
. Je suppose que ce nom est leur nom d'affichage et qu'il est unique. Quelle que soit la valeur que vous mettez ici, elle DOIT ÊTRE UNIQUE .
De là, vous pouvez saisir le guide de l'utilisateur.
Regarde ça.
using System.Web.Security;
....
// NOTE: This is a static method .. which makes things easier to use.
MembershipUser user = Membership.GetUser(User.Identity.Name);
if (user == null)
{
throw new InvalidOperationException("User [" +
User.Identity.Name + " ] not found.");
}
// Do whatever u want with the unique identifier.
Guid guid = (Guid)user.ProviderUserKey;
Ainsi, chaque fois que vous souhaitez récupérer les informations utilisateur, vous devez les récupérer dans la base de données en utilisant la méthode statique ci-dessus.
Lisez tout sur Membership class et MembershipUser class sur MSDN.
En tant que tel, je mettrais en cache ce résultat afin que vous n'ayez pas besoin de continuer à frapper la base de données.
... cont from above....
Guid guid = (Guid)user.ProviderUserKey;
Cache.Add(User.Identity.Name, user.UserID); // Key: Username; Value: Guid.
Sinon, vous pouvez créer votre propre classe d'identité (qui hérite de IIdentity ) et ajouter vos propres propriétés personnalisées, comme UserID
. Ensuite, chaque fois que vous vous authentifiez (et également à chaque demande), vous pouvez définir cette valeur. Quoi qu'il en soit, c'est une solution de noyau dur, alors allez-y avec la mise en cache, maintenant.
HTH
User.Identity
est un IPrincipal
- généralement de type System.Web.Security.FormsIdentity
Il ne sait rien des UserID - c'est juste une abstraction du concept d'une "identité".
L'interface IIdentity n'a que 'Nom' pour un utilisateur, pas même 'Nom d'utilisateur'.
Si vous utilisez MVC4 avec la valeur par défaut SimpleMembershipProvider
vous pouvez le faire:
WebSecurity.GetUserId(User.Identity.Name) // User is on ControllerBase
(Où WebSecurity
est dans le paquet nuget Microsoft.AspNet.WebPages.WebData
dans WebMatrix
Vous pouvez aussi utiliser
WebSecurity.CurrentUserName
WebSecurity.CurrentUserId
(si vous utilisez ASPNetMembershipProvider qui est le plus ancien système d'adhésion ASPNET plus complexe, alors voyez la réponse de @ eduncan911)
Si vous utilisez l'appartenance à ASP.NET (qui à son tour utilise l'objet IPrincipal):
using System.Web.Security;
{
MembershipUser user = Membership.GetUser(HttpContext.User.Identity.Name);
Guid guid = (Guid)user.ProviderUserKey;
}
User.Identity renvoie toujours l'état de l'utilisateur actuel, connecté ou non.
Anonyme ou pas, etc. Un chèque est donc connecté:
if (User.Identity.IsAuthenticated)
{
...
}
Donc, tout mettre ensemble:
using System.Web.Security;
{
if (User.Identity.IsAuthenticated)
{
MembershipUser user = Membership.GetUser(HttpContext.User.Identity.Name);
Guid guid = (Guid)user.ProviderUserKey;
}
}
Meilleure option pour obtenir l'ID utilisateur
Ajouter des références ci-dessous
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;*
public myFunc()
{
.....
// Code which will give you user ID is
var tmp = User.Identity.GetUserId();
}
Si vous utilisez votre propre objet IPrincipal pour l'autorisation, il vous suffit de le caster pour accéder à l'ID.
Par exemple:
public class MyCustomUser : IPrincipal
{
public int UserId {get;set;}
//...Other IPrincipal stuff
}
Voici un excellent tutoriel sur la création de votre propre authentification basée sur un formulaire.
http://www.codeproject.com/KB/web-security/AspNetCustomAuth.aspx
Cela devrait vous permettre de créer un cookie d'authentification pour votre utilisateur et d'accéder à vos données utilisateur personnalisées.
using System.Web.Security;
MembershipUser user = Membership.GetUser(User.Identity.Name);
int id = Convert.ToInt32(user.ProviderUserKey);
Simple....
int userID = WebSecurity.CurrentUserId;
C'est la propriété ProviderUserKey.
System.Web.Security.MembershipUser u;
u.ProviderUserKey
Habituellement, vous pouvez simplement utiliser WebSecurity.currentUserId
, mais si vous êtes dans AccountController juste après la création du compte et que vous souhaitez utiliser l'ID utilisateur pour lier l'utilisateur à certaines données d'autres tables, alors WebSecurity.currentUserId
(et toutes les solutions ci-dessus), malheureusement, dans ce cas, renvoie -1, donc cela ne fonctionne pas.
Heureusement dans ce cas, vous avez le contexte db pour la table UserProfiles à portée de main, vous pouvez donc obtenir l'ID utilisateur par ce qui suit:
UserProfile profile = db.UserProfiles.Where(
u => u.UserName.Equals(model.UserName)
).SingleOrDefault();
Je suis tombé sur ce cas récemment et cette réponse m'aurait fait gagner beaucoup de temps, alors il suffit de le publier.