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;
}
}
[ASP.NET Identity 2.0]如何將 ASP.NET Identity 的資料表 PK 欄位的資料型別由 NVARCAHR(128) 改為 INT
ASP.NET Identity 2.0 所提供的資料表中 PK 欄位資料型別皆為 nvarchar(128) ,所儲存的值為 GUID 格式字串。
如果我們想將 PK 的資料型別改為 int 該如何作呢?
以下將一步步實現這個過程。
請建立一個 ASP.NET MVC 5 專案,驗證方式請選擇「個別使用者帳戶」。
打開並修改 Models\IdentityModels.cs 為以下程式碼
到這邊大部份重要的類別都改完了,這時建置一下專案後發現還有一些錯誤,讓我們接著來處理
調整 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>())
}
});
這樣我們就完成了 Table PK 由 nvarchar(128) 改為 int。