Asp.net-Mvc

使用 NHibernate.AspNet.Identity

  • July 7, 2016

我正在嘗試使用 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.SaveSession.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修復問題。

我只對更改後有效的庫進行了簡單的測試,因此不知道該庫中有多少其他執行時/邏輯錯誤。發現這些錯誤後,現在使用它讓我非常緊張。似乎即使是簡單的場景也絕對沒有進行過測試。小心使用這個庫。

引用自:https://stackoverflow.com/questions/21243269