使用 NHibernate.AspNet.Identity
我正在嘗試使用 Asp.net 身份和 NHibernate。
我已經使用 .NET 框架 4.5.1 創建了一個新的空白 Asp.net MVC 站點,並且我已經安裝並遵循了使用 nuget 包 NHibernate.AspNet.Identity 的說明,如下所述:
https://github.com/milesibastos/NHibernate.AspNet.Identity
這涉及對 AccountController 類預設建構子進行以下更改:
var mapper = new ModelMapper(); mapper.AddMapping<IdentityUserMap>(); mapper.AddMapping<IdentityRoleMap>(); mapper.AddMapping<IdentityUserClaimMap>(); mapper.AddMapping<IdentityUserLoginMap>(); var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities(); var configuration = new Configuration(); configuration.Configure(System.Web.HttpContext.Current.Server.MapPath(@"~\Models\hibernate.cfg.xml")); configuration.AddDeserializedMapping(mapping, null); var schema = new SchemaExport(configuration); schema.Create(true, true); var factory = configuration.BuildSessionFactory(); var session = factory.OpenSession(); UserManager = new UserManager<ApplicationUser>( new UserStore<ApplicationUser>(session));我收到以下異常:
沒有堅持:IdentityTest.Models.ApplicationUser
ApplicationUser 類對 IdentityUser 沒有任何附加屬性(這對於 Asp.net Identity 的實體框架實現工作正常)。
任何人都可以提供有關如何讓 Asp.net 身份與此 NuGet 包一起使用的建議嗎?
我一直在努力使用這個庫,這讓我質疑為什麼這是將 OWIN 與 NHibernate 一起使用的推薦庫。
無論如何,為了回答您的問題,您提供的從 github 網站獲得的程式碼為庫的類添加了 NHibernate 映射。NHibernate 沒有映射
ApplicationUser,它只有它的基類的映射。NHibernate 需要實例化類的映射。這是有問題的,因為您無法訪問庫程序集中的映射程式碼,因此您無法將其更改為使用ApplicationUser該類。因此,使用庫來解決這個問題的唯一方法是刪除ApplicationUser該類並使用該庫的IdentityUser類。或者,您可以從 github 複製映射程式碼並嘗試對ApplicationUser.此外,庫程式碼和他提供的程式碼
AccountController永遠不會打開 NHibernate 事務,因此即使庫呼叫Session.Save和Session.Update數據最終也不會保存在數據庫中。打開會話後,您需要打開一個事務並將其保存為類的私有欄位:transaction = session.BeginTransaction(IsolationLevel.ReadCommitted);然後你需要
transaction.Commit()在你的動作AccountController完成後呼叫,所以你需要覆蓋OnResultExecuted:protected override void OnResultExecuted(ResultExecutedContext filterContext) { transaction.Commit(); }請記住,此範例過於簡單,在生產應用程序中,您需要進行錯誤檢查,如果出現錯誤,您將在哪裡回滾而不是送出,並且您需要正確關閉/處理所有內容等。
此外,即使您解決了這些問題,圖書館也存在其他問題。我最終不得不從 github 下載原始碼,這樣我就可以修改庫以使用它。庫程式碼中至少還有 3 個其他明顯錯誤:
1)在NHibernate.AspNet.Identity.UserStore:
public virtual async Task<TUser> FindAsync(UserLoginInfo login) { this.ThrowIfDisposed(); if (login == null) throw new ArgumentNullException("login"); IdentityUser entity = await Task.FromResult(Queryable .FirstOrDefault<IdentityUser>( (IQueryable<IdentityUser>)Queryable.Select<IdentityUserLogin, IdentityUser>( Queryable.Where<IdentityUserLogin>( // This line attempts to query nhibernate for the built in asp.net // UserLoginInfo class and then cast it to the NHibernate version IdentityUserLogin, // which always causes a runtime error. UserLoginInfo needs to be replaced // with IdentityUserLogin (IQueryable<IdentityUserLogin>)this.Context.Query<UserLoginInfo>(), (Expression<Func<IdentityUserLogin, bool>>)(l => l.LoginProvider == login.LoginProvider && l.ProviderKey == login.ProviderKey)), (Expression<Func<IdentityUserLogin, IdentityUser>>)(l => l.User)))); return entity as TUser; }2)在NHibernate.AspNet.Identity.DomainModel.ValueObject:
protected override IEnumerable<PropertyInfo> GetTypeSpecificSignatureProperties() { var invalidlyDecoratedProperties = this.GetType().GetProperties().Where( p => Attribute.IsDefined(p, typeof(DomainSignatureAttribute), true)); string message = "Properties were found within " + this.GetType() + @" having the [DomainSignature] attribute. The domain signature of a value object includes all of the properties of the object by convention; consequently, adding [DomainSignature] to the properties of a value object's properties is misleading and should be removed. Alternatively, you can inherit from Entity if that fits your needs better."; // This line is saying, 'If there are no invalidly decorated properties, // throw an exception'..... which obviously should be the opposite, // remove the negation (!) if (!invalidlyDecoratedProperties.Any()) throw new InvalidOperationException(message); return this.GetType().GetProperties(); }3)在NHibernate.AspNet.Identity.UserStore:出於某種原因,至少在使用像 facebook 這樣的外部提供程序創建使用者/使用者登錄時,當最初創建使用者/使用者登錄時,呼叫 Update 方法而不是 Add /Create 導致 NHibernate 嘗試更新不存在的實體。現在,無需深入研究,在
UserStore更新方法中,我將庫的程式碼更改為呼叫SaveOrUpdateNHibernate 會話,而不是Update修復問題。我只對更改後有效的庫進行了簡單的測試,因此不知道該庫中有多少其他執行時/邏輯錯誤。發現這些錯誤後,現在使用它讓我非常緊張。似乎即使是簡單的場景也絕對沒有進行過測試。小心使用這個庫。