使用现有的数据库名称验证实现 OWIN?

Implementing OWIN using existing Database name validation?

我希望按照我可以在此处找到的示例实施 OWIN: http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api

但是,由于这种工作方式对我来说是新的,尤其是使用我自己创建的数据库时,我需要一些指导。 我可以毫无问题地提交我的注册请求。

post 将我带到 AccountController:

    [AllowAnonymous]
    [Route("Register")]
    public async Task<IHttpActionResult> Register(RegisterBindingModel model)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        try { 
            var email = model.Email;
            var password = model.Password;

            var user = new users() {
                 Email = email,
                 PasswordHash = password,
                 Password = password
            };

            IdentityResult result = await UserManager.CreateAsync(user, model.Password);

            if (!result.Succeeded)
            {
                return GetErrorResult(result);
            }

            return Ok();
        }
        catch(Exception ex)
        {
            throw;
        }
    }

这会触发以下代码:

    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

应用程序用户管理器:

public class ApplicationUserManager : UserManager<users>
{
    public ApplicationUserManager(IUserStore<users> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<users>(context.Get<DaumAuctionEntities>()));
        var dataProtectionProvider = options.DataProtectionProvider;

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = false,
            RequireDigit = false,
            RequireLowercase = true,
            RequireUppercase = true,
        };

        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<users>(dataProtectionProvider.Create("ASP.NET Identity"));
        }

        return manager;
    }
}

但由于某些奇怪的原因,我得到了

 modelState: {undefined: ["Name cannot be null or empty."]}

即使我没有在任何地方使用名字?!这个名字是从哪里来的?

所以我认为我做错了什么,但如果没有关于如何使用现有数据库实现 OWIN 的明确解释,很难调试。

在我的 context/entity 和我想用来存储我的用户数据的用户 table 下方。

上下文:

public partial class DaumAuctionEntities : IdentityDbContext<users>
{
    public DaumAuctionEntities()
        : base("name=DaumAuctionEntities")
    {
    }

    public DbSet<addresses> addresses { get; set; }
    public DbSet<auctions> auctions { get; set; }
    public DbSet<images> images { get; set; }
    public DbSet<users> users { get; set; }
}

用户:身份用户:

public partial class users : IdentityUser
{
    public override string UserName
    {
        get
        {
            return Email;
        }
        set
        {
            Email = value;
        }
    }

    override public string PasswordHash
    {
        get
        {
            return Password;
        }

        set
        {
            Password = value;
        }
    }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<users> manager, string authenticationType)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
        // Add custom user claims here
        return userIdentity;
    }
}

public partial class users
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public System.DateTime CreatedDate { get; set; }
    public Nullable<System.DateTime> ModifiedDate { get; set; }

}

编辑:

如果我在尝试调用 CreateAsync 之前将 UserName 添加回我的新用户对象,则错误消失但我得到另一个错误:

"The specified type member 'UserName' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."

编辑二:

我在教程代码中也有这个问题!这只是 .NET 中的一个可怕的错误?

编辑三

我尝试进行覆盖,正如您在上面的部分 class 用户中看到的那样。但是我仍然有同样的错误。

The issue is due to the fact that I did not add UserName to my new user before I call UserManager.CreateAsync. If I add the UserName I have the exact same issue as this: MVC 5 IdentityDbContext and DbContext transactions

这个问题似乎表明 ASP.NET Identity 在查询中使用了 UserName 属性,但是 Entity Framework 抱怨 属性 未映射到实体模型 (EDML) 中的数据库列。

我没发现你的代码有什么问题

  1. 从您的 DaumAuctionEntities 中删除用户 DbSet class(参见 this
  2. 从您的用户中删除 ID 属性 class
  3. 在 Register 中创建新用户时设置 CreatedDate 属性 方法

那你应该没问题

此外,关于:

Nope, it actually passes that. It comes from I believe the manager but whenever I try to debug that code the debugger states that it jumped over it (most likely due to the fact that it's an external library from Microsoft).

如果您用 try/catch 包装调用,您将能够看到错误消息

我对您在此处共享的代码几乎没有问题,但与您提到的不完全相同。我已经在 git 上分享了示例,供您参考。自己尝试一下,如果发现任何问题请告诉我。

Git URL - https://github.com/JitJDN/OWINStack

看,代码还是和你的一样:

var 电子邮件 = model.Email; var 密码 = model.Password;

        var user = new users()
        {
            Email = email,
            PasswordHash = password,
            Password = password
        };

        IdentityResult result = await UserManager.CreateAsync(user, model.Password);

        if (!result.Succeeded)
        {
            return GetErrorResult(result);
        }

        return Ok();

我终于成功了。

最后我不得不添加调整部分 class 用户(这是我的 SQL 数据库中的 table)以便用户名和密码覆盖 IDentityUser 的字段(所以不像我在我的问题中所做的那样):

public partial class users
{
    public int Id { get; set; }
    public string UserName {get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }    
    public DateTime? CreatedDate { get; set; }
    public DateTime? ModifiedDate { get; set; }
}

然后我在创建用户时只需要传递密码和用户名:

        var user = new users() {
             Email = email,
             UserName = email, 
             PasswordHash = password,
             Password = password
        };