Search code examples
c#asp.netasp.net-corerazor

How to use PartialAsync() twice and still get input from either one of the Partial Async renders


I am using a MainLogin.cshtml component to choose whether to load up the Register or Login page, based off of whether there are or aren't users in the Database.

However, instead of creating a user when I register, the website throws an error, saying that Input is null (i.e Input.Password)

Here is MainLogin.cshtml:

@model Path.To.MainLoginModel

@{
}

@if (Model.ShowRegister)
{
    @await Html.PartialAsync("Path/To/Register.cshtml", Model.registerModel);
}
else{
    @await Html.PartialAsync("Path/To/Login.cshtml", Model.loginModel);

}

And here is the code behind it, MainLogin.cshtml.cs:

public class MainLoginModel : PageModel
    {
        private readonly IMediator mediator;
        public readonly RegisterModel registerModel;
        public readonly LoginModel loginModel;
        public MainLoginModel(IMediator mediator, RegisterModel registerModel, LoginModel loginModel)
        {
            this.mediator = mediator;
            this.registerModel = registerModel;
            this.loginModel = loginModel;
        }
        public bool ShowRegister { get; set; }
        public async Task<IActionResult> OnGetAsync()
        {
            ShowRegister = (await mediator.Send(new CheckUsers())).UsersDontExist;
            return Page();
        }

        public async Task OnPostAsync()
        {
            ShowRegister = (await mediator.Send(new CheckUsers())).UsersDontExist;
            if (ShowRegister)
            {
                await registerModel.OnPostAsync();
            }
            else
            {
                await loginModel.OnPostAsync();
            }
        }
    }

Both RegisterModel and LoginModel have the InputModel class defined inside them:

public class InputModel
        {
            public string Email { get; set; }
            public string Password { get; set; }
            public string ConfirmPassword { get; set; }
        }

The Login and Register pages both worked fine until I tried to make them share space on one page, which makes me think that PartialAsync() is to blame, but I don't know how to fix that.


Solution

  • Please check this document related:

    A partial view is a Razor markup file (.cshtml) without a @page directive that renders HTML output within another markup file's rendered output.

    In another words,it's Razor View instead of Razor Page, doesn't have handler(onGet,OnPost...)

    So,If you want to share same content between Register Page and Login Page You should create a partial View or work with another Layout Page for the two razor page above,not treate the two Pages as partial view

    In your Login/Register Page:

    @await Html.PartialAsync("SharedContent.cshtml", sharedModel);
    

    add a Razor View(Notice not Razor Page) SharedContent.cshtml

    Check in the handler of Login Page:

    public IActionResut YourHandler ()
    {
    
        If(!user.exists)
        {
          return RedirecttoPage("Register")
        }
    }