在Identity Custom User之后,User.Identity.GetUserId()将错误的类型返回为字符串

我为entity framework和asp.net身份创建了自定义用户模型。 我在这里检查了其他答案,他们接近我的问题,但答案不符合我的要求。 所以我在这里问。

一切都好。 但是当我尝试获得用户ID时:

ApplicationUser user = await manager.FindByIdAsync(User.Identity.GetUserId()); 

User.Identity.GetUserId()返回字符串。 我像Guid一样配置它。 但它返回字符串:(

我的课程在这里。 请帮助我,如何在Web api控制器中将User.Identity.GetUserId()作为Guid获取?

 public class GuidUserLogin : IdentityUserLogin { } public class GuidUserRole : IdentityUserRole { } public class GuidUserClaim : IdentityUserClaim { } public class GuidRole : IdentityRole { } //public class GuidUserContext : IdentityDbContext { } public class GuidUserStore : UserStore { public GuidUserStore(DbContext context) : base(context) { } } public class GuidRoleStore : RoleStore { public GuidRoleStore(DbContext context) : base(context) { } } public class ApplicationUser : IdentityUser, ICreateDateRequired { public ApplicationUser() { } [Key] public Guid UserId { get; set; } public override Guid Id { get; set; } public override string UserName { get; set; } public string Name { get; set; } public string Surname { get; set; } public string Password { get; set; } //Matching Attributes public override string Email { get; set; } public string FacebookId { get; set; } public string TwitterId { get; set; } public string GoogleId { get; set; } public override string PhoneNumber { get; set; } public string SocialAccessToken { get; set; } public string Gender { get; set; } public virtual List Shades { get; set; } [InverseProperty("ParentUser")] public virtual List Friends { get; set; } public virtual List Contacts { get; set; } //[Column(TypeName = "DateTime2")] //[DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime? CreateDate { get; set; } public string ImageUrl { get; set; } public string ThumbUrl { get; set; } public string BackUrl { get; set; } public virtual List UserContactDetails { get; set; } } 

GetUserId的定义是这样的:

 public static string GetUserId(this IIdentity identity); public static T GetUserId(this IIdentity identity) where T : IConvertible; 

不幸的是,Guid不是IConvertible,它不会返回通用forms的Guid类型。 因此,我们不能使用: User.Identity.GetUserId()因为有些人在将ID更改为Int时使用User.Identity.GetUserId()

因此你应该使用Guid.Parse()Guid.TryParse()

 Guid.Parse(User.Identity.GetUserId()) 

@Erik方法工作正常,但由于我不想覆盖原始方法,我添加了以下一般扩展:

  public static class ExtensionMethods { public static Guid ToGuid(this string value) { Guid result= Guid.Empty; Guid.TryParse(value, out result); return result; } } 

然后我用了这个:

 User.Identity.GetUserId().ToGuid() 

编辑:我提出了另一个解决方案:

我添加了Identity对象的扩展。

 public static class IdentityExtensions { public static Guid GetGuidUserId(this IIdentity identity) { Guid result = Guid.Empty; Guid.TryParse(identity.GetUserId(), out result); return result; } } 

GetUserId()实际上是以下扩展方法:

 Microsoft.AspNet.Identity.IdentityExtensions.GetUserId(this IIdentity identity) 

在某些时候,没有办法将值存储为Guid (cookies!)。 这意味着你必须手动更改它(我今天就自己做了)。 我所做的是将使用Microsoft.AspNet.IdentityMicrosoft.AspNet.Identity.OwinMicrosoft.Owin.Security所有内容移动到一个单独的目录中。 然后写了我自己的扩展类:

 internal static class IIdentityExtensions { public static Guid GetUserId(this IIdentity identity) { var result = Guid.Empty; string id = Microsoft.AspNet.Identity.IdentityExtensions.GetUserId(identity); Guid.TryParse(id, out result); return result; } public static string GetUserName(this IIdentity identity) { string result = Microsoft.AspNet.Identity.IdentityExtensions.GetUserName(identity); return result; } public static string FindFirstValue(this ClaimsIdentity identity, string claimType) { string result = Microsoft.AspNet.Identity.IdentityExtensions.FindFirstValue(identity, claimType); return result; } } 

只需确保检查Guid.Empty (或将其更改为Guid?)。 你会发现有很多东西只接受string ,你必须转换它们。 例如:

 namespace Microsoft.Owin.Security { public static class AuthenticationManagerExtensions { public static ClaimsIdentity CreateTwoFactorRememberBrowserIdentity( this IAuthenticationManager manager, string userId); public static Task TwoFactorBrowserRememberedAsync( this IAuthenticationManager manager, string userId); } } 

所以你必须使用.GetUserId().ToString()来使用某些方法。

对于我们的项目,我需要基于IUserKey抽象密钥(并将标识符存储为此接口中的long )。

通过简单地覆盖用户密钥对象的具体实现中的ToString()方法,解决了(严重依赖于字符串的UserManager的问题ToString()

 public class IdentityUserKey : IIdentityUserKey { public long UserId { get; set; } public bool Equals(IIdentityUserKey other) { return other != null && other.UserId == UserId; } public override string ToString() { return UserId.ToString(); } } 

在你的情况下,也许你可以在一个类似的界面中包装Guid ,然后提供必要的ToString()覆盖。