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 enter image description here

But if I run without breakpoints I get an unhandled exception enter image description here

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!

0

There are 0 best solutions below