在标识自定义用户之后,User.Identity. getuserid()返回错误的字符串类型

本文关键字:返回 错误 类型 字符串 getuserid Identity 自定义 标识 用户 之后 User | 更新日期: 2023-09-27 18:02:55

我为实体框架和asp.net标识创建了自定义用户模型。我检查了这里的其他答案,它们接近我的问题,但答案不符合我的要求。所以我在这里问。

一切正常。但是当我尝试获取用户id时,比如:

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

User.Identity.GetUserId()返回字符串。我把它配置成Guid。但是它返回字符串:(

我的课在这里。请帮助我,我怎么能得到User.Identity.GetUserId()在一个web api控制器作为Guid ?

public class GuidUserLogin : IdentityUserLogin<Guid>
    {
    }

    public class GuidUserRole : IdentityUserRole<Guid>
    {
    }
    public class GuidUserClaim : IdentityUserClaim<Guid>
    {
    }
    public class GuidRole : IdentityRole<Guid, GuidUserRole>
    {
    }
//public class GuidUserContext : IdentityDbContext<ApplicationUser, GuidRole, Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> { }
    public class GuidUserStore : UserStore<ApplicationUser, GuidRole, Guid, GuidUserLogin, GuidUserRole, GuidUserClaim>
    {
        public GuidUserStore(DbContext context)
            : base(context)
        {
        }
    }
    public class GuidRoleStore : RoleStore<GuidRole, Guid, GuidUserRole>
    {
        public GuidRoleStore(DbContext context)
            : base(context)
        {
        }
    }

    public class ApplicationUser : IdentityUser<Guid, GuidUserLogin, GuidUserRole, GuidUserClaim>, 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<Shade> Shades { get; set; }
        [InverseProperty("ParentUser")]
        public virtual List<UserFriendship> Friends { get; set; }
        public virtual List<Contact> 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<ContactDetail> UserContactDetails { get; set; }
    }

在标识自定义用户之后,User.Identity. getuserid()返回错误的字符串类型

GetUserId的定义如下:

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

不幸的是,Guid不是一个不可转换的,它不会返回通用形式的Guid类型。因此,我们不能使用:User.Identity.GetUserId()<Guid>,因为有些人在将ID更改为Int时使用User.Identity.GetUserId()<Int>

因此您应该使用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 (cookie !)。这意味着你必须手动更改它(我今天刚刚自己这么做了)。我所做的是将所有使用Microsoft.AspNet.Identity, Microsoft.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<bool> TwoFactorBrowserRememberedAsync(
      this IAuthenticationManager manager, 
      string userId);
  }
}

所以你必须.GetUserId().ToString()某些方法的工作

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

通过简单地在user key对象的具体实现中覆盖ToString()方法,解决了UserManager严重依赖字符串的问题。

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()覆盖。