Reputation: 1604
I am using the ASP.NET identity but I would like to validate the user with different fields instead of using the email (or username) and the password.
In my scenario the user has a keycode instead of the email. That keycode field I know how to add to the IdentityUser
through the ApplicationUser
but I found trouble when I need to check if it exists in the database. The UserManager
has methods to find the user by username and password (or email) but not for the custom properties I added (obviously).
I tried to implement my own UserManager
but it seemed such a big effort for quite "simple" thing. I just need one extra method.
One solution is using the username as the field to store the keycode. However I don't like the idea very much. It is not very clean, feels like cheating; and I may need that field in the future for its original purpose.
Is a solution with a better a trade-off between complexity and clean solution?
Thank you very much in advance!
Upvotes: 1
Views: 226
Reputation: 3869
The limitation is in the IUserStore (only has Create, Update, Delete, FindById and FindByName(username) methods) that's what the UserManager is using to retrive the data from the database. So if you want to extend the UserManager with a new function that gives you an user by keycode you also needs to extend the IUserStore.
In general I dont like the solution of putting "wrong data" in a property. So, to extend the UserManager and the UserStore regarding your needs, you do like this:
First extend the IUserStore interface
public interface IMyUserStore : IUserStore<User>
{
Task<User> FindByKeyCodeAsync(string keyCode);
}
Implement the new interface
public class MyUserStore : UserStore<User>, IMyUserStore
{
public Task<User> FindByKeyCodeAsync(string keyCode)
{
return Users.Where(x => x.KeCode == keyCode);
}
}
Extend the UserManager
public class MyUserManager : UserManager<User>
{
private readonly IMyUserStore _store;
public MyUserManager(IMyUserStore store)
: base(store)
{
_store = store;
}
public virtual Task<User> FindByKeyCodeAsync(string keyCode)
{
var a = new UserStore<User>();
return _store.FindByKeyCodeAsync(keyCode);
}
}
And if you want to get a user by any parameter it has you can change the FindByKeyCodeAsync method to:
public Task<User> Find(Expression<Func<User, bool>> expression)
{
return Users.SingleAsync(expression);
}
Upvotes: 2