🫘
ASP.NET Identityでユーザーに紐付いた別テーブルの情報を、DBアクセスなしにページヘッダに表示する方法
契約情報があって、その下に複数のユーザーをぶら下げるという構成の場合。(契約情報=ユーザーとしてもいいんだろうけど、担当者の変更などを考えると複数ユーザーにできたほうがよいと思った。)
ユーザーテーブルに契約情報テーブルを関連付ける
まずASP.NET Identityでユーザーテーブルに契約情報テーブルを関連付けたい。
調べた結果ApplicationUserは普通のモデルクラスなのでCode Firstなら単純に関連テーブルとして定義してやればいい。
public enum SubscriptionKind
{
Free = 0,
Standard = 1,
}
public enum SubscriptionStatus
{
Active = 0,
Cancelled = 1,
}
public class Subscription
{
public int ID { get; set; }
public SubscriptionKind SubscriptionKind { get; set; }
public SubscriptionStatus SubscriptionStatus { get; set; }
}
public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
public int SubscriptionId { get; set; }
public virtual Subscription Subscription { get; set; }
public DateTime CreatedDate { get; set; }
}
契約情報をクレームに追加する
さらに契約情報をページヘッダに表示したい。毎回DBアクセスしたくないのでクレーム用Cookieから読み込みたい。
public class ApplicationClaimTypes
{
public const string SubscriptionKind = "http://example.com/claims/subscriptionkind";
public const string SubscriptionStatus = "http://example.com/claims/subscriptionstatus";
}
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);
// ここにカスタム ユーザー クレームを追加します
userIdentity.AddClaim(new Claim(ApplicationClaimTypes.SubscriptionKind, this.Subscription.SubscriptionKind.ToString()));
userIdentity.AddClaim(new Claim(ApplicationClaimTypes.SubscriptionStatus, this.Subscription.SubscriptionStatus.ToString()));
return userIdentity;
}
}
GenerateUserIdentityAsync()でクレームを追加してやるといいらしい。他のタイミングじゃダメなんだろうか。。?
契約情報をページヘッダに表示する
これで_Layout.cshtmlなどからDBアクセスせずに契約情報を表示できた。
<li>契約種別: @Html.Raw(((System.Security.Claims.ClaimsIdentity)User.Identity).FindFirst(ApplicationClaimTypes.SubscriptionKind).Value)</li>
こりゃ便利ですな。
Discussion