Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

After Identity Custom User , User.Identity.GetUserId() returns wrong type as string

I created custom User model for entity framework and asp.net identity. I checked other answers in here, they are close to my question but answers not apply my requirement. so i am asking here.

Everything is ok. But when i try to get user id like :

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

User.Identity.GetUserId() return string. I configured it like Guid. But it returns string :(

My classes are here. Please help me, how can i get User.Identity.GetUserId() in a web api controller as 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; }
    }
like image 968
Ras Avatar asked May 13 '14 02:05

Ras


2 Answers

The definition of GetUserId is this:

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

Unfortunately Guid is not an IConvertible and it will not return the Guid type in the Generic form. Therefore, we can not use: User.Identity.GetUserId()<Guid> as some people use User.Identity.GetUserId()<Int> when they change the ID to Int.

Therefore you should use Guid.Parse() or Guid.TryParse()

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

@Erik method works fine, But As I did not wanted to override the original one, I added the following general extension:

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

and then I used this:

User.Identity.GetUserId().ToGuid()

Edit: I came up with another solution:

I added an extension to the Identity object.

public static class IdentityExtensions
{
    public static Guid GetGuidUserId(this IIdentity identity)
    {
        Guid result = Guid.Empty;
        Guid.TryParse(identity.GetUserId(), out result);
        return result;
    }   
}
like image 174
Amir Avatar answered Nov 12 '22 14:11

Amir


GetUserId() is actually the following extension method:

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

At some point there is no way to store a value as a Guid (cookies!). This means you'll have to manually change it (I just did this myself today). What I did was moved everything that uses Microsoft.AspNet.Identity, Microsoft.AspNet.Identity.Owin and Microsoft.Owin.Security into a separate directory. Then wrote my own Extension Class:

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;
    }
}

Just make sure you check for Guid.Empty (or change it to Guid?). You'll find that there are quite a few things that just accept string, and you'll have to convert them. For example:

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);
  }
}

So you'll have to .GetUserId().ToString() for certain methods to work.

like image 24
Erik Philips Avatar answered Nov 12 '22 14:11

Erik Philips