I'm working on a new Visual Studio 2019 webapp project with asp.net core MVC 3.1, razor pages and scaffolded Identity. I'm using a custom IdentityUser class
public class VivaceApplicationUser : IdentityUser
{
[PersonalData]
public string FirstName { get; set; }
[PersonalData]
public string LastName { get; set; }
//[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
[PersonalData]
public DateTime DateOfBirth { get; set; }
[PersonalData]
public Address Address { get; set; }
[PersonalData]
public string AdditionaInfos { get; set; }
[PersonalData]
public LoginUserStatus Status { get; set; }
[PersonalData]
public bool hasPaidQuote { get; set; }
[DataType(DataType.Date)]
[PersonalData]
public DateTime paidOnDate { get; set; }
[DataType(DataType.Date)]
[PersonalData]
public DateTime paidValidity { get; set; }
[DataType(DataType.Date)]
[PersonalData]
public DateTime registeredSince { get; set; }
}
public enum LoginUserStatus
{
Submitted,
Approved,
Rejected
}
This class use an Address class defined as follows:
public class Address
{
public int AddressID { get; set; }
public string City { get; set; }
public int PostalCode { get; set; }
public string Street { get; set; }
public string CivicNumber { get; set; }
}
My ApplicationDbContext class looks like that:
public class ApplicationDbContext : IdentityDbContext<VivaceApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Address> Addresses { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
I can login in my webapp and create a new user. In the database I can see the new user and his address as well (in the address table). In the dbo.AspNetUsers I can also see the right AdressID.
My issue is now in deleting a user in the DeletePersonalDataModel class.
public class DeletePersonalDataModel : PageModel
{
private readonly UserManager<VivaceApplicationUser> _userManager;
private readonly SignInManager<VivaceApplicationUser> _signInManager;
private readonly ILogger<DeletePersonalDataModel> _logger;
private readonly ApplicationDbContext _context;
public DeletePersonalDataModel(
UserManager<VivaceApplicationUser> userManager,
SignInManager<VivaceApplicationUser> signInManager,
ILogger<DeletePersonalDataModel> logger,
ApplicationDbContext context)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_context = context;
}
[BindProperty]
public InputModel Input { get; set; }
public class InputModel
{
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
public Address Address { get; set; }
}
public bool RequirePassword { get; set; }
public async Task<IActionResult> OnGet()
{
// Get user
var user = await _userManager.GetUserAsync(User);
// Get user from _context
var userFromContext = await _context.Users.FindAsync(user.Id);
// Get user address from _context
var addressFromContext = await _context.Addresses.FindAsync(user.Address.AddressID);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (addressFromContext == null)
{
return NotFound($"Unable to load user address of user with ID '{_userManager.GetUserId(User)}'.");
}
RequirePassword = await _userManager.HasPasswordAsync(user);
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
// Get user
var user = await _userManager.GetUserAsync(User);
// Get user address from _context
var addressFromContext = await _context.Addresses.FindAsync(user.Address.AddressID);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (addressFromContext == null)
{
return NotFound($"Unable to load user address with ID '{_userManager.GetUserId(User)}'.");
}
RequirePassword = await _userManager.HasPasswordAsync(user);
if (RequirePassword)
{
if (!await _userManager.CheckPasswordAsync(user, Input.Password))
{
ModelState.AddModelError(string.Empty, "Incorrect password.");
return Page();
}
}
var result = await _userManager.DeleteAsync(user);
var resultRemoveAddress = _context.Addresses.Remove(addressFromContext);
var userId = await _userManager.GetUserIdAsync(user);
if (!result.Succeeded)
{
throw new InvalidOperationException($"Unexpected error occurred deleting user with ID '{userId}'.");
}
//if (!resultRemoveAddress.)
//{
// throw new InvalidOperationException($"Unexpected error occurred deleting user address of user with ID '{userId}'.");
//}
await _context.SaveChangesAsync();
await _signInManager.SignOutAsync();
_logger.LogInformation("User with ID '{UserId}' deleted themselves.", userId);
return Redirect("~/");
}
}
I can get the current (logged) user from the _userManager class in the OnGet() method
// Get user
var user = await _userManager.GetUserAsync(User);
I can also get the current (logged) user from the _contect class in the OnGet() method
// Get user from _context
var userFromContext = await _context.Users.FindAsync(user.Id);
And I can get the user's address from the _context class as well in the OnGet() method
// Get user address from _context
var addressFromContext = await _context.Addresses.FindAsync(user.Address.AddressID);
Setting a breakpoint on
// Get user
var user = await _userManager.GetUserAsync(User);
in the OnGet() method and waiting a couple of seconds I see this
But if I run without breakpoints I get an unhandled exception
What I'm doing wrong? And how to solve this issue?
If I run with breakpoints the database gets updated correctly. Both the user and his address get deleted.
Thanks very much!