How to give custom implementation of UpdateAsync method of asp.net identity? - c#

I am doing custom asp.net identity and not using asp.net inbuilt tables.I have successfully created user with implementing custom CreateAsync
Now i want to update user with new encrypted password and so i am not getting how to provide custom implementation of UpdateAsync method.
This is my table:
User : Id,Name,EmailId,Password,Statistics,Salary
Model:
public class UserModel : IUser
{
public string Id { get; set; }
public string Name { get; set; }
public string EmailId { get; set; }
public string Password { get; set; }
public int Salary { get; set; }
}
My custom class which implements IUserstore:
public class UserStore : IUserStore<UserModel>, IUserPasswordStore<UserModel>
{
private readonly MyEntities _dbContext;
private readonly HttpContext _httpContext;
// How to implement this method for updating only user password
public Task UpdateAsync(UserModel user)
{
throw new NotImplementedException();
}
public Task CreateAsync(UserModel user)
{
return Task.Factory.StartNew(() =>
{
HttpContext.Current = _httpContext ?? HttpContext.Current;
var user = _dbContext.User.Create();
user.Name = user.Name;
user.EmailId = user.EmailId;
user.EmailAddress = user.Email;
user.Password = user.Password;
_dbContext.Users.Add(dbUser);
_dbContext.SaveChanges();
});
}
public Task SetPasswordHashAsync(UserModel user, string passwordHash)
{
return Task.Factory.StartNew(() =>
{
HttpContext.Current = _httpContext ?? HttpContext.Current;
var userObj = GetUserObj(user);
if (userObj != null)
{
userObj.Password = passwordHash;
_dbContext.SaveChanges();
}
else
user.Password = passwordHash;
});
}
public Task<string> GetPasswordHashAsync(UserModel user)
{
//other code
}
}
Controller:
public class MyController : ParentController
{
public MyController()
: this(new UserManager<UserModel>(new UserStore(new MyEntities())))
{
}
public UserManager<UserModel> UserManager { get; private set; }
[HttpPost]
public async Task<JsonResult> SaveUser(UserModel userModel)
{
IdentityResult result = null;
if (userModel.Id > 0) //want to update user with new encrypted password
result = await UserManager.UpdateAsync(user);
else
result = await UserManager.CreateAsync(userModel.EmailId, userModel.Password);
}
}

Not sure if this is what your looking for...
public Task UpdateAsync(UserModel model)
{
var user = _dbContext.User.Find(x => x.id == model.id);
user.Password = model.Password;
_dbContext.SaveChanges();
return Task.CompletedTask;
}
It Will get the specific record and Update the password and then save the record.
Edit
Since the password is not getting encrypted i added code to take that string and leave the model as it is, this extension method will encrypt the value of password, i have not test this but i am sure it will work.
user.Password = model.Password.EncryptPassword(EncryptKey);
Extension methods to encrypt password

Sometime back, I created a complete wrapper over .NET Identity and code can be found here. It might be helpful for you. You can also find nuget here. I also explained the library in a blog here.

Related

ASP.NET Core Web API - Put action with DTO didn't update the existing object

I've been trying to write Put (update) action without the id property, by using DTO. But every time I'm trying I'm getting the existing object and not the updated one, and I can't figure out why and how to change it so it will work.
My repository:
public User Update(Guid id, User user)
{
var userToUpdate=_context.Users.FirstOrDefault(x => x.Id == id);
_context.Entry(userToUpdate).State = EntityState.Modified;
_context.SaveChanges();
return userToUpdate;
}
My DTO:
public class UserPostDTO
{
public UserPostDTO()
{
}
public UserPostDTO(User user)
{
UserName= user.UserName;
Password= user.Password;
LastLogin= user.LastLogin;
}
[StringLength(255)]
public string UserName { get; set; } = null!;
[StringLength(255)]
public string Password { get; set; } = null!;
[Column(TypeName = "datetime")]
public DateTime? LastLogin { get; set; }
public User ToPostUser()
{
var user = new User();
user.UserName = UserName;
user.Password = Password;
user.LastLogin = LastLogin;
return user;
}
}
My Controller:
public class UserController : ControllerBase
{
private readonly IUserRepository _userRepository;
public UserController(IUserRepository userRepository)
{
_userRepository = userRepository;
}
[HttpPut("{id}")]
public IActionResult Put(Guid id, [FromBody] UserPostDTO user)
{
_userRepository.Update(id, user.ToPostUser());
return Ok();
}
Didn't see you updating the User object with the new value.
Probably this is what you need:
public User Update(Guid id, User user)
{
var userToUpdate = _context.Users.FirstOrDefault(x => x.Id == id)
.AsNoTracking();
if (userToUpdate == null)
{
// Handle ID is not existed
throw new ArgumentNullException("ID is not existed");
}
user.Id = userToUpdate.Id;
_context.Entry(user).State = EntityState.Modified;
_context.SaveChanges();
return user;
}

Attempt to implement repository pattern for an MVC app causes a concurrency exception

I am learning ASP .NET Core and I am trying to use repository pattern to clean up my controllers. The way I thought this out was:
create a repository interface containing the basic methods for a repository
implement the previously created the interface
create a model based repository interface
create a model-based repository extending the basic repository created at step 2 and implemented the model-based interface
create a wrapper class which contains the context and all the application repositories and inject it in every controller
Unfortunately the Complete of 'Edit' method causes a DbConcurrencyException which I have tried to solve using this. using the previous solution causes an InvalidOperationException as one of the properties is read-only.
For some code:
public class User : IdentityUser
{
[PersonalData]
[DisplayName("First Name")]
[Required(ErrorMessage = "The first name is required!")]
[StringLength(30, MinimumLength = 3, ErrorMessage = "The first name must be between 3 and 30 characters long!")]
public string firstName { get; set; }
[PersonalData]
[DisplayName("Last Name")]
[Required(ErrorMessage = "The last name is required!")]
[StringLength(30, MinimumLength = 3, ErrorMessage = "The last name must be between 3 and 30 characters long!")]
public string lastName { get; set; }
[PersonalData]
[DisplayName("CNP")]
[Required(ErrorMessage = "The PNC is required!")]
[StringLength(13, MinimumLength = 13, ErrorMessage = "The last name must 13 digits long!")]
[RegularExpression(#"^[0-9]{0,13}$", ErrorMessage = "Invalid PNC!")]
public string personalNumericalCode { get; set; }
[PersonalData]
[DisplayName("Gender")]
[StringRange(AllowableValues = new[] { "M", "F" }, ErrorMessage = "Gender must be either 'M' or 'F'.")]
public string gender { get; set; }
public Address address { get; set; }
}
public class Medic : User
{
[DisplayName("Departments")]
public ICollection<MedicDepartment> departments { get; set; }
[DisplayName("Adiagnostics")]
public ICollection<MedicDiagnostic> diagnostics { get; set; }
[PersonalData]
[DisplayName("Rank")]
[StringLength(30, MinimumLength = 3, ErrorMessage = "The rank name must be between 3 and 30 characters long!")]
public string rank { get; set; }
}
public class MedicController : Controller
{
private readonly IUnitOfWork unitOfWork;
public MedicController(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
// GET: Medic
public async Task<IActionResult> Index()
{
return View(await unitOfWork.Medics.GetAll());
}
// GET: Medic/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null)
{
return NotFound();
}
Medic medic = await unitOfWork.Medics.FirstOrDefault(m => m.Id == id);
if (medic == null)
{
return NotFound();
}
return View(medic);
}
// GET: Medic/Create
public IActionResult Create()
{
return View();
}
// POST: Medic/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("rank,firstName,lastName,personalNumericalCode,Id,gender,Email")] Medic medic)
{
if (ModelState.IsValid)
{
unitOfWork.Medics.Add(medic);
await unitOfWork.Complete();
return RedirectToAction(nameof(Index));
}
return View(medic);
}
// GET: Medic/Edit/5
public async Task<IActionResult> Edit(string id)
{
if (id == null)
{
return NotFound();
}
Medic medic = await unitOfWork.Medics.Get(id);
if (medic == null)
{
return NotFound();
}
return View(medic);
}
// POST: Medic/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("rank,firstName,lastName,Id,personalNumericalCode,gender,Email")] Medic medic)
{
if (id != medic.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
var saved = false;
while (!saved)
{
try
{
unitOfWork.Medics.Update(medic);
await unitOfWork.Complete();
saved = true;
}
catch (DbUpdateConcurrencyException ex)
{
if (!MedicExists(medic.Id))
{
return NotFound();
}
else
{
foreach (var entry in ex.Entries)
{
if (entry.Entity is Medic)
{
var proposedValues = entry.CurrentValues;
var databaseValues = entry.GetDatabaseValues();
foreach (var property in proposedValues.Properties)
{
var proposedValue = proposedValues[property];
var databaseValue = databaseValues[property];
proposedValues[property] = proposedValue;
// TODO: decide which value should be written to database
// proposedValues[property] = <value to be saved>;
}
// Refresh original values to bypass next concurrency check
entry.OriginalValues.SetValues(databaseValues);
}
else
{
throw new NotSupportedException(
"Don't know how to handle concurrency conflicts for "
+ entry.Metadata.Name);
}
}
}
}
}
return RedirectToAction(nameof(Index));
}
return View(medic);
}
// GET: Medic/Delete/5
public async Task<IActionResult> Delete(string id)
{
if (id == null)
{
return NotFound();
}
Medic medic = await unitOfWork.Medics.FirstOrDefault(m => m.Id == id);
if (medic == null)
{
return NotFound();
}
return View(medic);
}
// POST: Medic/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
Medic medic = await unitOfWork.Medics.Get(id);
unitOfWork.Medics.Remove(medic);
await unitOfWork.Complete();
return RedirectToAction(nameof(Index));
}
private bool MedicExists(string id)
{
return unitOfWork.Medics.Any(e => e.Id == id);
}
}
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly ApplicationDbContext context;
public Repository(ApplicationDbContext context)
{
this.context = context;
}
public void Add(TEntity entity)
{
context.Set<TEntity>().AddAsync(entity);
}
public void AddRange(IEnumerable<TEntity> entities)
{
context.Set<TEntity>().AddRangeAsync(entities);
}
public bool Any(Expression<Func<TEntity, bool>> predicate)
{
return context.Set<TEntity>().Any(predicate);
}
public async Task<IEnumerable<TEntity>> Find(Expression<Func<TEntity, bool>> predicate)
{
return await context.Set<TEntity>().Where(predicate).ToListAsync();
}
public async Task<TEntity> FirstOrDefault(Expression<Func<TEntity, bool>> predicate)
{
return await context.Set<TEntity>().FirstOrDefaultAsync(predicate);
}
public async Task<TEntity> Get(string id)
{
return await context.Set<TEntity>().FindAsync(id);
}
public async Task<IEnumerable<TEntity>> GetAll()
{
return await context.Set<TEntity>().ToListAsync();
}
public void Remove(TEntity entity)
{
context.Set<TEntity>().Remove(entity);
}
public void RemoveRange(IEnumerable<TEntity> entities)
{
context.Set<TEntity>().RemoveRange(entities);
}
public TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate)
{
return context.Set<TEntity>().SingleOrDefault(predicate);
}
public void Update(TEntity entity)
{
context.Set<TEntity>().Update(entity);
}
}
public class MedicRepository : Repository<Medic>, IMedicRepository
{
public MedicRepository(ApplicationDbContext _context) : base(_context) { }
//TODO: add medic repository specific methods
}
public class UnitOfWork : IUnitOfWork
{
private readonly ApplicationDbContext _context;
public IMedicRepository Medics { get; private set; }
public IPatientRepository Patients { get; private set; }
public IReceptionistRepository Receptionists { get; private set; }
public IDiagnosticRepository Diagnostics { get; private set; }
public IMedicationRepository Medications { get; private set; }
public IMedicineRepository Medicine { get; private set; }
public ILabTestRepository LabTests { get; private set; }
public ILabResultRepository LabResults { get; private set; }
public UnitOfWork(ApplicationDbContext context)
{
_context = context;
Medics = new MedicRepository(_context);
Patients = new PatientRepository(_context);
Receptionists = new ReceptionistRepository(_context);
Diagnostics = new DiagnosticRepository(_context);
Medications = new MedicationRepository(_context);
Medicine = new MedicineRepository(_context);
LabTests = new LabTestRepository(_context);
LabResults = new LabResultRepository(_context);
}
public async Task<int> Complete()
{
return await _context.SaveChangesAsync();
}
public void Dispose()
{
_context.Dispose();
}
}
Thanks!
There are a lot of things to notice. But I will only point to the biggest one. DbContext or ApplicationDbContext classes are not meant to be long lived and cross spanned. I am guessing ApplicationDbContext is a singleton. Which is a long lived object and is shared among different classes and also may be threads. This is exactly the design pattern you should avoid. In terms of Microsoft -
Entity Framework Core does not support multiple parallel operations being run on the same DbContext instance. Concurrent access can result in undefined behavior, application crashes and data corruption. Because of this it's important to always use separate DbContext instances for operations that execute in parallel.
This page here describes the problem - https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext#avoiding-dbcontext-threading-issues
In short, use scoped dbcontext.
If you are learning, I would say implement it yourself and change the implementations of your classes. Create and dispose contexts when you need them. Do not keep long lived contexts.
If you just need a repository, you can use this package, I use it for myself - https://github.com/Activehigh/Atl.GenericRepository
I managed to fix this out. The concurrency exception was thrown because I was creating users (which were inheriting IDentityUser) without using a UserManager<User>. After inspecting the database fields, I have discovered that the Identityuser related fields (like email, username, etc..) were empty. This was due to me only adding information for the class which inherited IDentityUser.

how to customize a sign in method using Identity

I have an element that derives from IdentityUser which contains a property called AppId. I'm trying to customize the SignInManager.PasswordSignInAsync, so it includes the AppId (from AspNetUsers where AppId = id).
is this even possible?
what I have so far:
public class LCUserManager
{
public LCUserManager(IdentityDbContext context)
{
this.DbContext = context;
}
public async Task<IProfile> SignIn(int appId, string userName, string password)
{
IProfile result = default;
PasswordHasher<Profile> hash = new PasswordHasher<Profile>();
var tmp = this.DbContext.Profiles.SingleOrDefault(u => u.Active && u.AppId.Equals(appId) && u.NormalizedUserName.Equals(userName.ToNormalized()));
if (tmp != default)
{
}
else
{
}
}
public IIdentityDbContext DbContext { get; }
}

ChangepasswordAsync not work

I used this code for admin panel to changed password of customer by manager,I did not get any Error. but password not changed,
i got my coed from this
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult ChangeUserPassword(SetPasswordViewModel model,string userId)
{
if (ModelState.IsValid)
{
//var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
ApplicationUser appUser = db.Users.Find(userId);
var result = UserManager.ChangePasswordAsync(appUser, model.NewPassword);
if (result.IsCompleted)
{
var user = UserManager.FindById(User.Identity.GetUserId());
//var user = db.Users.Find(userId);
if (user != null)
{
//await SignInManager<,>.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageController.ManageMessageId.SetPasswordSuccess });
}
// AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
and in controller for change use this
public async Task<IdentityResult> ChangePasswordAsync(ApplicationUser Appuser, string newPassword)
{
var store = this.Store as Microsoft.AspNet.Identity.IUserPasswordStore<ApplicationUser,string>;
if (store == null)
{
var errors = new string[]
{
"Current UserStore doesn't implement IUserPasswordStore"
};
return IdentityResult.Failed(errors);
// return Task.FromResult(new IdentityResult(errors) { Succeeded = false });
}
var newPasswordHash = this.PasswordHasher.HashPassword(newPassword);
await store.SetPasswordHashAsync(Appuser, newPasswordHash);
await store.UpdateAsync(Appuser);
//return await Task.FromResult<IdentityResult>(IdentityResult.Success);
return IdentityResult.Success;
}
}
whats my mistake?
after update answer i use this method instead
[HttpPost]
public async Task<IdentityResult> ChangePasswordAsync(ApplicationUser appuserId, string newPassword)
{
ApplicationDbContext db = new ApplicationDbContext();
//var userr =await db.Users.FirstOrDefaultAsync(x => x.Id == appuserId.Id);
var newPasswordHash = this.PasswordHasher.HashPassword(newPassword);
db.Entry(Users).State = EntityState.Modified;
if (appuserId != null) appuserId.PasswordHash = newPasswordHash;
db.SaveChanges();
return IdentityResult.Success;
}
but had the same problem again
in IdentityModels.cs i had
public DbSet<CommonAction> CommonActions { get; set; }
public DbSet<PublicContent> PublicContents { get; set; }
public DbSet<MainSubject> MainSubjects { get; set; }
public DbSet<EducationLevel> EducationLevels { get; set; }
public DbSet<TimePeriod> TimePeriods { get; set; }
public DbSet<HelpType> HelpTypes { get; set; }
public DbSet<FinancialSupport> FinancialSupports { get; set; }
public DbSet<LinksStatistic> LinksStatistics { get; set; }
public DbSet<SlideOfCommonAction> SlideOfCommonActions { get; set; }
in normal model IdentityModel User is not register as DbSet
()
You're not awaiting ChangePasswordAsync, you're just checking if it's completed or not. Which may result in the View being returned before the password has been changed.
Then you should try to use async/await all the way, if possible. That means that your action should be async as well.
[HttpPost]
[ValidateAntiForgeryToken]
public virtual async Task<ActionResult> ChangeUserPassword(SetPasswordViewModel model,string userId)
{
if (ModelState.IsValid)
{
//var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
ApplicationUser appUser = db.Users.Find(userId);
// await the result.
var result = await UserManager.ChangePasswordAsync(appUser, model.NewPassword);
if (result.Succeeded) // Or whatever you're expecting.
{
var user = UserManager.FindById(User.Identity.GetUserId());
//var user = db.Users.Find(userId);
if (user != null)
{
//await SignInManager<,>.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageController.ManageMessageId.SetPasswordSuccess });
}
// AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
Update after comments:
The entity type DbSet`1 is not part of the model for the current context
db.Entry(Users).State = EntityState.Modified;
This is when EF cannot connect your model to an entity in the context. Without seeing the code, it's hard to say exactly why. But it could be that your're missing a DbSet in your context.
Have you configured your UserManager correctly? Does the other UserManager actions work?
Try debugging and see where it crashes.

How best to override the authentication in MVC 5?

I have a project in which does not have registration. Administrator registers users in admin. The project does not have the roles, I have only one type of user. I do not need "AspNetRoles", "AspNetUserClaims", "AspNewUserLogins", "AspNetUserRoles". And in the table "AspNetUsers" I need only "Id", "Email", "Password" and a few custom properties. What is the best way to implement this in mvc 5?
To Add more columns/fields to AspNetUsers you need to add those in Identity Model adn do Data Migration using -update database command
you can also control the Keys and Table Name by Overriding as below
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
modelBuilder.Entity<ApplicationUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
modelBuilder.Entity<IdentityUserRole>().ToTable("MyUserRoles");
modelBuilder.Entity<IdentityUserLogin>().ToTable("MyUserLogins");
modelBuilder.Entity<IdentityUserClaim>().ToTable("MyUserClaims");
modelBuilder.Entity<IdentityRole>().ToTable("MyRoles");
}
When you are using ASPNET Schema for user registration, I don't think you can avoid Claims,Roles and other tables, but you can just ignore those.
Update
In order to avoid Roles and Claims in ASPNET membership
First of all create a MVC 5 application. Then implement IUser,
public class ApplicationUser : IUser
{
public ApplicationUser()
{
this.Id = Guid.NewGuid().ToString();
}
public ApplicationUser(string userName): this()
{
UserName = userName;
}
public virtual string Id { get; set; }
public virtual string PasswordHash { get; set; }
public virtual string SecurityStamp { get; set; }
public virtual string UserName { get; set; }
}
Next we need a DbContet to store the Users,
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
public virtual IDbSet<ApplicationUser> Users { get; set; }
}
and then we need to implement IUserStore, IUserPasswordStore and IUserSecurityStampStore,
public class MyUserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>, IUserSecurityStampStore<ApplicationUser>
{
UserStore<IdentityUser> userStore = new UserStore<IdentityUser>(new ApplicationDbContext());
public MyUserStore()
{
}
public Task CreateAsync(ApplicationUser user)
{
var context = userStore.Context as ApplicationDbContext;
context.Users.Add(user);
context.Configuration.ValidateOnSaveEnabled = false;
return context.SaveChangesAsync();
}
public Task DeleteAsync(ApplicationUser user)
{
var context = userStore.Context as ApplicationDbContext;
context.Users.Remove(user);
context.Configuration.ValidateOnSaveEnabled = false;
return context.SaveChangesAsync();
}
public Task<ApplicationUser> FindByIdAsync(string userId)
{
var context = userStore.Context as ApplicationDbContext;
return context.Users.Where(u => u.Id.ToLower() == userId.ToLower()).FirstOrDefaultAsync();
}
public Task<ApplicationUser> FindByNameAsync(string userName)
{
var context = userStore.Context as ApplicationDbContext;
return context.Users.Where(u => u.UserName.ToLower() == userName.ToLower()).FirstOrDefaultAsync();
}
public Task UpdateAsync(ApplicationUser user)
{
var context = userStore.Context as ApplicationDbContext;
context.Users.Attach(user);
context.Entry(user).State = EntityState.Modified;
context.Configuration.ValidateOnSaveEnabled = false;
return context.SaveChangesAsync();
}
public void Dispose()
{
userStore.Dispose();
}
public Task<string> GetPasswordHashAsync(ApplicationUser user)
{
var identityUser = ToIdentityUser(user);
var task = userStore.GetPasswordHashAsync(identityUser);
SetApplicationUser(user, identityUser);
return task;
}
public Task<bool> HasPasswordAsync(ApplicationUser user)
{
var identityUser = ToIdentityUser(user);
var task = userStore.HasPasswordAsync(identityUser);
SetApplicationUser(user, identityUser);
return task;
}
public Task SetPasswordHashAsync(ApplicationUser user, string passwordHash)
{
var identityUser = ToIdentityUser(user);
var task = userStore.SetPasswordHashAsync(identityUser, passwordHash);
SetApplicationUser(user, identityUser);
return task;
}
public Task<string> GetSecurityStampAsync(ApplicationUser user)
{
var identityUser = ToIdentityUser(user);
var task = userStore.GetSecurityStampAsync(identityUser);
SetApplicationUser(user, identityUser);
return task;
}
public Task SetSecurityStampAsync(ApplicationUser user, string stamp)
{
var identityUser = ToIdentityUser(user);
var task = userStore.SetSecurityStampAsync(identityUser, stamp);
SetApplicationUser(user, identityUser);
return task;
}
private static void SetApplicationUser(ApplicationUser user, IdentityUser identityUser)
{
user.PasswordHash = identityUser.PasswordHash;
user.SecurityStamp = identityUser.SecurityStamp;
user.Id = identityUser.Id;
user.UserName = identityUser.UserName;
}
private IdentityUser ToIdentityUser(ApplicationUser user)
{
return new IdentityUser
{
Id = user.Id,
PasswordHash = user.PasswordHash,
SecurityStamp = user.SecurityStamp,
UserName = user.UserName
};
}
}
For password hash and security stamp, I am using the UserStore's implementation for making thing simpler. Finally we just need to change AccountController's constructor to leverage our MyUserStore implementation,
public AccountController()
: this(new UserManager<ApplicationUser>(new MyUserStore()))
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
To Drop unnecessary columns in Users Table. You can try somethign like this
public partial class ModifyUser: DbMigration
{
public override void Up()
{
AddColumn("dbo.AspNetUsers", "NewField", c => c.String());
}
public override void Down()
{
DropColumn("dbo.AspNetUsers", "NewColumn");
}
}
Then in packageManager run PM> update-database

Categories

Resources