如果我們想將 PK 的資料型別改為 int 該如何作呢?
以下將一步步實現這個過程。
請建立一個 ASP.NET MVC 5 專案,驗證方式請選擇「個別使用者帳戶」。
- 打開並修改 Models\IdentityModels.cs 為以下程式碼
namespace WebApplication1.Models { // 您可以在 ApplicationUser 類別新增更多屬性,為使用者新增設定檔資料,請造訪 http://go.microsoft.com/fwlink/?LinkID=317594 以深入了解。 public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim> { public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager) { // 注意 authenticationType 必須符合 CookieAuthenticationOptions.AuthenticationType 中定義的項目 var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // 在這裡新增自訂使用者宣告 return userIdentity; } } public class ApplicationUserRole : IdentityUserRole<int> { } public class ApplicationUserLogin : IdentityUserLogin<int> { } public class ApplicationUserClaim : IdentityUserClaim<int> { } public class ApplicationRole : IdentityRole<int, ApplicationUserRole> { } public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim> { public ApplicationDbContext() : base("DefaultConnection") { } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } } }
- 打開並修改 App_Start\IdentityConfig.cs 的 ApplicationUserManager 類別
public class ApplicationUserManager : UserManager<ApplicationUser, int> { public ApplicationUserManager(IUserStore<ApplicationUser, int> store) : base(store) { } public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) { var manager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context.Get<ApplicationDbContext>())); // 設定使用者名稱的驗證邏輯 manager.UserValidator = new UserValidator<ApplicationUser, int>(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; // 設定密碼的驗證邏輯 manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, }; // 註冊雙因素驗證提供者。此應用程式使用手機和電子郵件接收驗證碼以驗證使用者 // 您可以在這裡寫下自己的提供者和外掛程式。 manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser, int> { MessageFormat = "Your security code is: {0}" }); manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser, int> { Subject = "安全碼", BodyFormat = "Your security code is: {0}" }); manager.EmailService = new EmailService(); manager.SmsService = new SmsService(); var dataProtectionProvider = options.DataProtectionProvider; if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, int>(dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } }
調整 User.Identity.GetUserId() 擴充方法
在 AccountController.cs 中大量使用了 GetUserId() 擴充方法,他是用來從 Identity 中擷取 UserId。
會發生錯誤是因為我們現在的 UserId 定義為 int,而這個擴充方法會回傳 string,因此我們需要自建一個擴充方式來處理這個問題。
建立完成後我們將所有使用到的 GetUserId() 方法,改為 GetUserId<int>()。
記得有使用到自建的擴充方法檔案中要 using WebApplication1.ExtensionMethods 命名空間
using System.Security.Principal; using Microsoft.AspNet.Identity; namespace WebApplication1.ExtensionMethods { public static class IdentityExtensions { public static T GetUserId<T>(this IIdentity identity) where T : IConvertible { return (T)Convert.ChangeType(identity.GetUserId(), typeof(T)); } } }
再來將 ConfirmEmail 方法的 userId 參數,資料型別由 string 改為 int。
最後我們 Startup 中的 app.UseCookieAuthentication…程式碼換掉
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(TimeSpan.FromMinutes(30), regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager), getUserIdCallback: (identity) => identity.GetUserId<int>()) } });
參考資料:
http://stackoverflow.com/questions/22547712/asp-net-identity-change-guid-to-int
https://aspnetidentity.codeplex.com/workitem/2186