[英]ASP.NET Identity's UserManager caches users?
我們將ASP.NET Identity 2.2與ASP.NET MVC 5.2,Entity Framework 6.2和Unity 5.7一起使用。
我們有一個類ConnectUserManager
,它派生自ASP.NET Identity的UserManager
。 每次都會將新構建的UserStore
傳遞給UserManager
。
ConnectUserManager
(以及UserManager
)的生命周期是每個請求:
Container.RegisterType<ConnectUserManager>(
new PerRequestLifetimeManager(),
new InjectionConstructor(
Container.Resolve<ConnectDbContext>(),
Container.Resolve<ITemplateManager>(),
Settings.MaxFailedAccessAttemptsBeforeLockout,
Settings.AccountLockoutTimeSpan));
當我們需要顯示給定用戶的詳細信息時,控制器操作將檢索用戶:
public async Task<ActionResult> Details(int id)
{
var user = await UserManager.FindByIdAsync(id);
...
}
其中UserManager
是一個注入屬性:
[Dependency]
public ConnectUserManager UserManager { get; set; }
問題是user
似乎來自緩存 :數據庫中的修改似乎對我們的應用程序顯示的內容沒有任何影響。
這段代碼已經生產了一年,我們從來沒有遇到任何問題:當我們的代碼修改用戶時,緩存似乎正確無效。
我們現在才注意到這個問題,因為當Identity將用戶鎖定時,它會更新用戶的LockoutEndDateUtc
屬性,但似乎沒有使緩存失效,我們在顯示中得到一個陳舊的LockoutEndDateUtc
值。
我們做錯了什么?
編輯 :
@DotNetMatt在評論中鏈接了以下問題:
aspnet Identity中的實體框架緩存 。
除非我遺漏了某些東西,否則所接受的解決方案(無論如何寫作)似乎與原始海報和我的問題完全無關。
然而,原始海報似乎自己找到了(a?)解決方案:“我所做的是實現我自己的用戶界面並手動訪問EF並使用.AsNoTracking()來避免緩存。”
有沒有辦法做到這一點,而無需重新實現(或子類)用戶存儲?
這是EF僥幸。 身份沒有任何內置緩存。 我懷疑你的生活時間ConnectDbContext
是ConnectDbContext
是依賴的,而不是每個請求。
那么一旦ConnectDbContext
實例返回實例o ApplicationUser
,會發生什么。 然后另一個ConnectDbContext
實例執行鎖定。 但是當你回到ConnectDbContext
的第一個實例時,它對其他東西所做的更新一無所知。 因此,當您第二次獲得相同的實例時,它不會進入數據庫,它會返回已經跟蹤過該用戶的實例。
修復此問題的方法 - 確保您的生命周期范圍與所涉及的所有活動部件匹配: ConnectUserManager
, UserStore
和ConnectDbContext
。 因此,無論何時從DB獲取對象,它始終都是為您提供此功能的ConnectDbContext
的相同實例。
你也鏈接到的答案 - 看到最后的評論,OP說他有同樣的范圍問題。
我發現了我的問題。 @trailmax是正確的(在他自己的回答的評論中),我有俘虜的依賴關系。
該錯誤實際上是我的問題中的代碼片段,它配置了ConnectUserManager
依賴項的注入:
Container.RegisterType<ConnectUserManager>(
new PerRequestLifetimeManager(),
new InjectionConstructor(
Container.Resolve<ConnectDbContext>(),
Container.Resolve<ITemplateManager>(),
Settings.MaxFailedAccessAttemptsBeforeLockout,
Settings.AccountLockoutTimeSpan));
與以下版本不同,這一次 ,現在和現在解決了ConnectDbContext
依賴項:
Container.RegisterType<ConnectUserManager>(
new PerRequestLifetimeManager(),
new InjectionFactory(
container => new ConnectUserManager(
container.Resolve<ConnectDbContext>(),
container.Resolve<ITemplateManager>(),
Settings.MaxFailedAccessAttemptsBeforeLockout,
Settings.AccountLockoutTimeSpan)));
每次構造一個新的ConnectUserManager
時 ,它都能正確解析依賴關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.