使用现有的数据库名称验证实现 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) 中的数据库列。
我没发现你的代码有什么问题
- 从您的 DaumAuctionEntities 中删除用户 DbSet class(参见 this)
- 从您的用户中删除 ID 属性 class
- 在 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
};
我希望按照我可以在此处找到的示例实施 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) 中的数据库列。
我没发现你的代码有什么问题
- 从您的 DaumAuctionEntities 中删除用户 DbSet class(参见 this)
- 从您的用户中删除 ID 属性 class
- 在 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
};