0

I use the Asp.net Identity to create my membership module follow this tutorial http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity , and then I noticed I can't define the INT type primary key, cause the user model should inherit the IdentityUser, and in IdentityUser class defined the Id property is string type like this, how to solve it?

namespace Microsoft.AspNet.Identity.EntityFramework
{
    public class IdentityUser : IUser
    {
        public IdentityUser();
        public IdentityUser(string userName);

        public virtual ICollection<IdentityUserClaim> Claims { get; }
        **public virtual string Id { get; set; }**
        public virtual ICollection<IdentityUserLogin> Logins { get; }
        public virtual string PasswordHash { get; set; }
        public virtual ICollection<IdentityUserRole> Roles { get; }
        public virtual string SecurityStamp { get; set; }
        public virtual string UserName { get; set; }
    }
}
tereško
  • 58,060
  • 25
  • 98
  • 150
Rwing
  • 490
  • 4
  • 19

1 Answers1

2

You cant change the base ID of the IdentityUser using the default membership provider. You will have to roll your own IUser implementation and storage.

There is a great topic over here How to change type of id in Microsoft.AspNet.Identity.EntityFramework.IdentityUser that talks about creating your own implementation.

Now that being said (in my personal opinion [stop debate about int vs uniqueidentifier for primary key storage and indexing]) the Identity of the UserID (Id) property is a better unique user ID than an integer. Although the class is implemented as a string its underlying type is based on a Guid (see appendix 1 at bottom of answer) which is much harder to spoof than an ID. A sequential user ID gives someone an upper hand in understand how to locate other users and possibly get around application security. No I don't have examples handy, just doesn't smell good to me.

If you don't want to roll your own and it is possible to adjust your application I would suggest just exposing another property to your ApplicationModel class. This property would be responsible for converting the string Id column from IdentityUser to a Guid. In addition to this I would override the Id property (although keep the logic the same) to add a nice intelisense hint that the ID property should be used.

public class ApplicationUser : IdentityUser
{
    /// <summary>
    /// The unique User GUID
    /// </summary>
    [NotMapped]
    public Guid ID
    {
        get { return Guid.Parse(this.Id); }
        set { this.Id = value.ToString(); }
    }

    /// <summary>
    /// weak userid reference. Use the property <seealso cref="WebApplication6.Models.ID"/> instead
    /// </summary>
    public override string Id { get { return base.Id; } set { base.Id = value; } }
}

As you see above we just add another property ID of type Guid with the NotMapped attribute. (The attribute is to prevent EF from trying to store this value) The getters and setters of this property just parse the Guid of the base string Id.

Now this is just an idea, you could happily (and probably a better option) write your own as you see fit for your application.

Appendix 1 : IndentityUser constructor.

Below is the constructor a new IdentityUser from the Microsoft.AspNet.Identity.EntityFramework. assembly: note the id is set to Guid.NewGuid().ToString()

public IdentityUser()
{
    this.Id = Guid.NewGuid().ToString();
    this.Claims = new List<IdentityUserClaim>();
    this.Roles = new List<IdentityUserRole>();
    this.Logins = new List<IdentityUserLogin>();
}
Community
  • 1
  • 1
Nico
  • 12,493
  • 5
  • 42
  • 62
  • thanks very much, damnit microsoft why not solve this easiest small problem! – Rwing Jan 27 '14 at 03:53
  • @Rwing its actually part of the IUser implementation design. But I know what you mean. Hope this helps. – Nico Jan 27 '14 at 03:55
  • Can someone please clarify if this answer only pertains to Identity 1.0? The release of Identity 2.0 mentions the ability to specify a TKey to let you change this datatype. (I just can't seem to figure out how to get this to work so I can't speak with any certainty.) – Funka May 08 '14 at 22:33
  • @Funka if you haven't figured it out simply do IUser that does the trick in version 2.0 – Casper Sloth Paulsen Jun 08 '14 at 07:57
  • Thank you Casper, I had forgotten I left this comment but I did figure this out and can confirm this. For posterity or anyone else coming across this, yes it is now easier to change the type of the primary key on both the `IdentityUser` and the `IdentityRole` with the release of Identity 2.0.0. The ASP.NET team talked about this in their 2.0.0 release notes and have a nice sample app showing how to do this at https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/ChangePK/readme.txt – Funka Jun 11 '14 at 18:11
  • @Nico It did not work for me and the tables created by code first has PK with the type of string instead of int. Any idea? – Jack Aug 02 '16 at 20:17