use*_*706 11 nhibernate asp.net-mvc asp.net-identity
我试图使用Asp.net身份和NHibernate.
我使用.NET framework 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));
Run Code Online (Sandbox Code Playgroud)
我收到以下异常:
没有持久性:IdentityTest.Models.ApplicationUser
ApplicationUser类没有IdentityUser的任何其他属性(适用于Asp.net Identity的Entity Framework实现).
任何人都可以提供关于如何让Asp.net身份与这个NuGet包一起使用的建议吗?
wir*_*_in 20
我对这个库非常努力,这让我怀疑为什么这是推荐使用OWIN和NHibernate的库.
无论如何,为了回答你的问题,你从github网站获得的代码为库的类添加了NHibernate映射.NHibernate没有映射ApplicationUser
,它只有一个映射它的基类.NHibernate需要实例化类的映射.这是有问题的,因为您无权访问库程序集中的映射代码,因此您无法将其更改为使用ApplicationUser
该类.因此,使用库的唯一方法就是删除ApplicationUser
类并使用库的IdentityUser
类.或者,您可以从github复制映射代码并尝试使用相同的映射ApplicationUser
.
此外,库代码和他为此提供的代码AccountController
永远不会打开NHibernate事务,因此即使库调用Session.Save
并且Session.Update
数据最终也不会保存在数据库中.打开会话后,您需要打开一个事务并将其保存为类中的私有字段:
transaction = session.BeginTransaction(IsolationLevel.ReadCommitted);
Run Code Online (Sandbox Code Playgroud)
然后你需要transaction.Commit()
在AccountController
完成执行后的动作后调用,所以你需要覆盖OnResultExecuted
:
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
transaction.Commit();
}
Run Code Online (Sandbox Code Playgroud)
请记住,此示例过于简单,在生产应用程序中,您需要进行错误检查,如果出现错误,您将回滚而不是提交,并且需要正确关闭/处理所有内容等.
此外,即使解决了这些问题,库也存在其他问题.我最终不得不从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;
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
3)在NHibernate.AspNet.Identity.UserStore中:出于某种原因,至少在使用像facebook这样的外部提供程序创建用户/用户登录时,最初创建用户/用户登录时,将调用Update方法而不是Add /创建导致NHibernate尝试更新不存在的实体.现在,在没有进一步研究的情况下,在UserStore
更新方法中,我更改了库的代码,以便SaveOrUpdate
在NHibernate会话上调用而不是Update
修复问题.
我只使用在我的更改后工作的库运行简单测试,因此无法知道此库中有多少其他运行时/逻辑错误.找到这些错误后,现在让我真的很紧张.即使是简单的场景,似乎也没有完成任何测试.请谨慎使用此库.
我也很努力使用NHibernate.AspNet.Identity.我发现使用NHibernate创建自己的实现要容易得多,我在这里已经变成了一个最小的工作示例:
https://github.com/MartinEden/NHibernate.AspNet.Identity.Example
它们的关键部分是NHibernate会话的简单实现IUserStore<TUser, TKey>
和IUserPasswordStore<TUser, TKey>
持久性.然后,只需要写一点胶水就可以告诉Owin使用该代码.
归档时间: |
|
查看次数: |
6657 次 |
最近记录: |