Search code examples
c#.netrazordrop-down-menurazor-pages

razor pages, select list comes empty after using return page()


I have a simple question for you. I'm using .NET core 7 with Razor Pages. I have an add page and I make category selection here. I get the category information from the database in the OnGet() method and send it to the page. No problems so far. When I save the form, my OnPostAddAsync() method works and I save it to the database, but if any error occurs during registration, I return the error message to the screen and use the "return Page()" method to prevent the user from losing the information entered. When I use this method, my category information is not listed in the dropdown. It is very important for me that the information entered by the user is not lost. That's why I don't use RedirectToPage(). Now how do I do this without refreshing the page, losing the user's information, and most importantly filling out my category list?

My OnGetAsync() Method:

       public async Task<IActionResult> OnGetAsync()
       {
           var response = await _category.List(SessionValues()[0]);

           if (response.Message == "Authentication Error")
           {
               HttpContext.Session.Remove("userToken");
               HttpContext.Session.Remove("userInfo");

               return new RedirectToPageResult("Login");
           }

           if (response.Status)
           {
               List<SelectListItem> List = new List<SelectListItem>();

               foreach (var item in response.Data)
               {
                   List.Add(new SelectListItem
                   {
                       Value = item.Id.ToString(),
                       Text = item.Name
                   });

                   Options = List;
               }
           }
           else
           {
               ToastrError = response.Message;
           }

           return Page();
       }

After the page loads

My OnPostAddAsync() Method:

public async Task<IActionResult> OnPostAddAsync(AddRequestModel addModel)
{
    var response = await _product.Add(SessionValues()[0]);

    if (response.Message == "Authentication Error")
    {
        HttpContext.Session.Remove("userToken");
        HttpContext.Session.Remove("userInfo");

        return new RedirectToPageResult("Login");
    }

    if (response.Status)
    {
        ToastrSuccess = response.Message;
        return new RedirectToPageResult("Add");
    }

    ToastrError = response.Message;
    return Page();
}

If an error is encountered exactly here, the code will execute "return Page()" with the message.

If "return Page()" runs after the OnPostAddAsync() method runs

Here are the properties I use:

        [ViewData]
        public string ToastrError { get; set; }

        [TempData]
        public string ToastrSuccess { get; set; }
        
        public AddRequestModel addModel { get; set; }

        public List<SelectListItem> Options { get; set; }

I searched a lot on the internet and tried many things but none of them worked.


Solution

  • Items that you populate in OnGet are not persisted across requests. Therefore you need to copy the code for populating the List<SelectListItem> in your OnPost method too:

    public async Task<IActionResult> OnPostAddAsync(AddRequestModel addModel)
    {
        var response = await _product.Add(SessionValues()[0]);
    
        if (response.Message == "Authentication Error")
        {
            HttpContext.Session.Remove("userToken");
            HttpContext.Session.Remove("userInfo");
    
            return new RedirectToPageResult("Login");
        }
    
        if (response.Status)
        {
            ToastrSuccess = response.Message;
            return new RedirectToPageResult("Add");
        }
        List<SelectListItem> List = new List<SelectListItem>();
    
        foreach (var item in response.Data) // or wherever the data comes from
        {
           List.Add(new SelectListItem
           {
              Value = item.Id.ToString(),
              Text = item.Name
           });
        }
        Options = List; // outside the loop - no need to reassign every iteration
        ToastrError = response.Message;
        return Page();
    }