3

I am using .NET Identity for authentication and authorization. For my registration page, I added two selectListItem properties in the InputModel class for dropdown lists.

The problem is, when the server-side validation failed, the dropdown lists lost their data as the page reloaded. Other basic data are saved.

I consulted several old posts on how to repopulate the dropdown list but still can't solve the problem. I don't know what exactly is being executed after the return Page() is called.

Thanks in advance.

Here's page model and methods:

public class InputModel
    {
        ......
        [Required]
        public string Name { get; set; }
        ......
        [ValidateNever]
        public IEnumerable<SelectListItem> RoleList { get; set; }
        [ValidateNever]
        public IEnumerable<SelectListItem> CompanyList { get; set; }
    }




public async Task OnGetAsync(string returnUrl = null)
    {
        ......
        ......
        Input = new InputModel()
        {
            RoleList = _roleManager.Roles.Select(x => x.Name).Select(i => new SelectListItem
            {
                Text = i,
                Value = i
            }),
            CompanyList = _unitOfWork.Company.GetAll().Select(i => new SelectListItem
            {
                Text = i.Name,
                Value = i.Id.ToString()
            })
        };
    }




public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {
        ......
        
        if (ModelState.IsValid)
        {
            var user = CreateUser();

            await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
            await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
            user.StreetAddress = Input.StreetAddress;
            user.City = Input.City;
            user.State = Input.State;
            user.PostalCode = Input.PostalCode;
            user.Name = Input.Name;
            user.PhoneNumber = Input.PhoneNumber;
            
            if(Input.Role == SD.Role_User_Comp)
            {
                user.CompanyId = Input.CompanyId;
            }
            var result = await _userManager.CreateAsync(user, Input.Password);

            if (result.Succeeded)
            {
                ......
                ......
            }
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
            
                
        }

      
        // If we got this far, something failed, redisplay form
        return Page();
    }
Yiyi You
  • 16,875
  • 1
  • 10
  • 22
  • have you tried returning RedirectToPage() instead of Page(). I fear that returning Page() skips your OnGet method and your select population. I don't know how this will affect security though. – TiltedTeapot Aug 15 '22 at 19:03
  • Your drop-down list is filled with what data? – demis15 Aug 15 '22 at 19:11

2 Answers2

0

You can try to set RoleList and CompanyList into OnPostAsync:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {
        ......
        
        if (ModelState.IsValid)
        {
            var user = CreateUser();

            await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
            await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
            user.StreetAddress = Input.StreetAddress;
            user.City = Input.City;
            user.State = Input.State;
            user.PostalCode = Input.PostalCode;
            user.Name = Input.Name;
            user.PhoneNumber = Input.PhoneNumber;
            
            if(Input.Role == SD.Role_User_Comp)
            {
                user.CompanyId = Input.CompanyId;
            }
            var result = await _userManager.CreateAsync(user, Input.Password);

            if (result.Succeeded)
            {
                ......
                ......
            }
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
            
                
        }
         RoleList = _roleManager.Roles.Select(x => x.Name).Select(i => new SelectListItem
            {
                Text = i,
                Value = i
            });
            CompanyList = _unitOfWork.Company.GetAll().Select(i => new SelectListItem
            {
                Text = i.Name,
                Value = i.Id.ToString()
            });
      
        // If we got this far, something failed, redisplay form
        return Page();
    }
Yiyi You
  • 16,875
  • 1
  • 10
  • 22
0

Also suffering from the same problem for the last few days. I solved it by using Yiyi You's method. Though I made a different function for assigning values to the Properties (in your case RoleList and CompanyList) then call it in both OnPostAsync and OnGetAsync

MATIN
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 06 '22 at 22:27