I am trying to a implement simple hardcoded login in Blazor project using HttpContext.SignInAsync as shown in provided code.HttpContext is null! After looking up the possible causes for this I found that Blazer Server Side will not send the HttpContext if the RenderMode is InteractiveServer. However, if i make the login page ServerStatic then the interaction (events) does not work. When I try adding OnParametersSet() event (see below in code) it reloads again and again, so that obviously does not help us get a value for HttpContext
App.Razor code (relevant parts):
<!DOCTYPE html><html lang="en"><head> ....<ImportMap /><HeadOutlet @rendermode="PageRenderMode" /></head><body><Routes @rendermode="PageRenderMode" /> ...</body></html>@code { [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; private IComponentRenderMode? PageRenderMode => HttpContext.AcceptsInteractiveRouting() ? InteractiveServer : null;// private IComponentRenderMode? PageRenderMode =>// HttpContext.Request.Path.StartsWithSegments("/Account") ? null : InteractiveServer; }Login.Razor code (relevant parts):
@page "/Account/login"@using Microsoft.AspNetCore.Components.Authorization@using Microsoft.AspNetCore.Mvc.Rendering@using Syncfusion.Blazor.Buttons@using System.Diagnostics@using System@using System.IO@using Microsoft.AspNetCore.Authentication@using System.Security.Claims@using Microsoft.AspNetCore.Authentication.Cookies@inject IWebHostEnvironment Environment@inject NavigationManager NavigationManager@inject AuthenticationStateProvider AuthenticationStateProvider<PageTitle>Login</PageTitle><style> ...</style><form @onsubmit="Submit" width="75%"> <div class="container"><label for="uname"><b>Username</b></label><input type="text" placeholder="Enter Username" @bind-value="@LoginReq.UserName" required><label for="psw"><b>Password</b></label><input type="password" placeholder="Enter Password" @bind-value="@LoginReq.Password" required><button type="submit">Login</button> </div><div class="container" style="background-color:#f1f1f1"><button type="button" class="cancelbtn" @onclick="@Cancel">Cancel</button> </div></form>@code{ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; LoginModel LoginReq { get; set; } = new LoginModel(); protected override void OnInitialized() { } // protected override void OnParametersSet() // { // if (HttpContext is null) // { // // If this code runs, we're currently rendering in interactive mode, so there is no HttpContext. // // The identity pages need to set cookies, so they require an HttpContext. To achieve this we // // must transition back from interactive mode to a server-rendered page. // NavigationManager.Refresh(forceReload: true); // } // } public async void Submit() { if (LoginReq.UserName == "username" && LoginReq.Password == "12345") { var claims = new List<Claim> { new Claim(ClaimTypes.Name, LoginReq.UserName) }; var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity)); HttpContext.Response.Redirect("/autofillpage"); } else NavigationManager.NavigateTo("Account/login", true); } public void Cancel() { NavigationManager.NavigateTo("Account/login", true); }} public class LoginModel { [Required(ErrorMessage = "Username is Required")] [RegularExpression(@"^[a-zA-Z0-9]+$", ErrorMessage = "Input Invalid")] public string UserName { get; set; } [Required(ErrorMessage = "Password is Required")] public string Password { get; set; } }