Using NHibernate.AspNet.Identity



我正在尝试使用asp.net身份和nhibernate。

我已经使用.NET Framework 4.5.1创建了一个新的空白ASP.NET MVC站点,并已安装并遵循了使用Nuget Package Nhibernate.aspnate.Sternity的说明,如下所述:

https://github.com/milesibastos/nhibernate.aspnet.sideity

涉及对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(@"~Modelshibernate.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));

我得到以下例外:

没有迫害:dentitytest.models.applicationuser

ApplicationUser类没有任何其他属性(对于ASP.NET身份的实体框架实现)。

任何人都可以提供有关我如何获得ASP.NET身份的建议吗?

我在这个库中非常挣扎,这让我质疑为什么这是将Owin与Nhibernate一起使用的推荐库。

无论如何,要回答您的问题,您从Github网站获得的代码添加了图书馆类的NHibernate映射。NHibernate没有ApplicationUser的映射,它的基类仅具有映射。Nhibernate需要为实例化类的映射。这是有问题的,因为您无法访问库的组件中的映射代码,因此您无法将其更改以使用ApplicationUser类。因此,使用库以原样的库来克服此问题的唯一方法是删除ApplicationUser类并使用库的IdentityUser类。或者,您可以从GitHub复制映射代码,并尝试使用ApplicationUser的相同映射。

另外,他为AccountController提供的库代码和代码永远不会打开NHIBERNATE事务,因此,即使库调用Session.SaveSession.Update,数据最终也不会保存在数据库中。打开会话后,您需要打开交易并将其保存为班上的私人字段:

transaction = session.BeginTransaction(IsolationLevel.ReadCommitted);

然后,您需要在AccountController完成操作后调用transaction.Commit(),因此您需要覆盖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)创建用户/用户登录时,调用更新方法,而不是添加/创建引起nHibernate以尝试更新不存在的实体。目前,在UserStore更新方法中,我更改了库的代码,以在NHIBERNATE会话上调用SaveOrUpdate,而不是解决问题的Update

我只对我更改后有效的库进行了简单的测试,因此在此库中没有任何其他运行时/逻辑错误。找到这些错误后,我现在真的很紧张。似乎甚至没有简单的场景都没有进行测试。谨慎使用此库。

我也很难使用nhibernate.aspnet.Identity。我发现,使用NHibernate进行自己的实现要容易得多,我将其变成了一个最小的工作示例:

https://github.com/martineden/nhibernate.aspnet.identity.example

它们的关键部分是使用NHibernate会话进行持久性的IUserStore<TUser, TKey>IUserPasswordStore<TUser, TKey>的简单实现。然后,这只是写一些胶水来告诉Owin使用该代码的问题。

相关内容

  • 没有找到相关文章

最新更新