Skip to content

Add Timer To Login Page In Blazor #61475

Open
@MahdiElahi

Description

@MahdiElahi

Hi
i create new blazor 8 web app auto render
I want to define a C# timer on the default login page razor


private TimeSpan timeLeft = TimeSpan.FromMinutes(1).Add(TimeSpan.FromSeconds(59));
private System.Timers.Timer? countdownTimer;

private void StartTimer()
{
    countdownTimer = new System.Timers.Timer(1000); // 1 second
    countdownTimer.Elapsed += (sender, e) =>
    {
        if (timeLeft.TotalSeconds > 0)
        {
            timeLeft = timeLeft.Subtract(TimeSpan.FromSeconds(1));
            InvokeAsync(StateHasChanged);
        }
        else
        {
            countdownTimer?.Stop();
        }
    };
    countdownTimer.Start();
}

But because the page uses SSR (server-side rendering), it doesn't work — when the time decreases, the page doesn't update at all; it basically doesn't work.

When I change the RenderMode to something like interactive server, it works fine.

But then, when I try to sign in, it throws a "headers are read-only, response has already started" error, meaning the page must use SSR.

Login.razor


@page "/admin-pro/account/sign-in"

@layout AuthLayout
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> userManager
@inject IUserAdminService authAdminService
@inject ILogger<Login> Logger
@inject NavigationManager NavigationManager
@inject IdentityRedirectManager RedirectManager

<PageTitle>Sign In</PageTitle>
<div class="card p-2 bg-opacity-8" id="form-s">
    <!-- Logo -->
    <div class="app-brand justify-content-center mt-2">
        <span class="app-brand-logo demo">
            <img src="/images/main-brand.png" width="350" />
        </span>
        @* <span class="app-brand-text demo text-heading fw-bold">Aircraft Finder</span> *@
    </div>
    <!-- /Logo -->
    <div class="card-body mt-2">

        <EditForm Model="Input" class="login-form mb-3" method="post" OnValidSubmit="LoginUser" FormName="login">
            <DataAnnotationsValidator />
            <div class="alert alert-solid-danger d-flex align-items-center @visibleError" role="alert">
                <i class="mdi mdi-alert-outline me-2"></i>
                @errorMessage
            </div>
            <div class="form-floating form-floating-outline mb-3">
                <InputText @bind-Value="Input.Username" type="text" class="form-control" placeholder="Enter your username" autofocus />
                <label for="email">Username</label>
                <ValidationMessage For="@(() => Input.Username)" />
            </div>
            <div class="mb-3">
                <div class="form-password-toggle">
                    <div class="input-group input-group-merge">
                        <div class="form-floating form-floating-outline">
                            <InputText @bind-Value="Input.Password" type="password" class="form-control" placeholder="Enter your password" />
                            <label for="password">Password</label>
                            <ValidationMessage For="@(() => Input.Password)" />
                        </div>
                    </div>
                </div>
            </div>
            <div class="mb-3 d-flex justify-content-between">
                <div class="form-check">
                    <input class="form-check-input" type="checkbox" id="remember-me">
                    <label class="form-check-label" for="remember-me">
                        Remember me
                    </label>
                </div>
            </div>
            <div class="mb-3">
                <button class="btn btn-primary d-grid w-100" type="submit">Sign In</button>
            </div>

        </EditForm>
        <div class="col-md-8 row m-auto mt-2">
            <p class="notice is-md text-right text-2 text-grays-500 mb-4  text-center " data-v-4c79b6d3="">
                <span class="fw-bold">@timeLeft.ToString(@"mm\:ss")</span>
                until you can request the code again
            </p>
        </div>
    </div>
</div>

@code {
    private string? errorMessage;
    private string visibleError = "d-none";
    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    [SupplyParameterFromForm]
    private LoginAdminDTO Input { get; set; } = new();

    [SupplyParameterFromQuery]
    private string? ReturnUrl { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (HttpMethods.IsGet(HttpContext.Request.Method))
        {
            // Clear the existing external cookie to ensure a clean login process
            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
        }
    }

    public async Task LoginUser()
    {
        var result = await authAdminService.LoginAsync(Input);
        if (result.Status is ResponseStatus.Success)
        {
            NavigationManager.NavigateTo("/admin-pro");
        }
        else
        {
            errorMessage = result.Message;
            visibleError = "";
        }
    }

    private TimeSpan timeLeft = TimeSpan.FromMinutes(1).Add(TimeSpan.FromSeconds(59));
    private System.Timers.Timer? countdownTimer;

    private void StartTimer()
    {
        countdownTimer = new System.Timers.Timer(1000); // 1 second
        countdownTimer.Elapsed += (sender, e) =>
        {
            if (timeLeft.TotalSeconds > 0)
            {
                timeLeft = timeLeft.Subtract(TimeSpan.FromSeconds(1));
                InvokeAsync(StateHasChanged);
            }
            else
            {
                countdownTimer?.Stop();
            }
        };
        countdownTimer.Start();
    }

    public void Dispose()
    {
        countdownTimer?.Dispose();
    }
}

and
Is it even possible to implement an interactive server or assembly so that I can build anything I want and not run into issues like 'Headers are read only...

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-identityIncludes: Identity and providers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions