Skip to content
IzzyBlazor 0.1.0-alpha.17

Enter all results ↑ ↓ move Esc close

The password is empty after a failed post

This is on purpose: a static page doesn't write a password back into its HTML. Ask for it again, and catch what you can before the form posts.

Problem

On a static page, a sign-in or sign-up form posts and the server turns it down. The page comes back with the other fields filled in and the error showing, but the password field is empty. On an interactive page the password stays.

Cause

After a static post, the page comes back as new HTML with each field's value in it. For a password that would send it back to the browser in the page itself, so, like most server-rendered forms, TextField leaves a password's value out on static pages. An interactive page updates the field in place, with no new HTML, so it keeps what was typed.

Fix

There's nothing to turn off. Make the empty field easy to deal with:

  • Say so. Put "Enter your password again" in the message, so the empty field isn't a surprise.
  • Check before posting. Keep NativeValidation on (the default): the browser checks [Required], lengths and formats before the form posts, so those mistakes keep the password.
  • Set AutoComplete. current-password or new-password lets a password manager fill it again.
SignIn.razor
<Form Model="Model" FormName="sign-in" OnValidSubmit="SignInAsync">
    @if (_failed)
    {
        <Alert Status="Status.Danger">
            That email and password don't match. Enter your password again.
        </Alert>
    }
    <TextField @bind-Value="Model!.Email" AutoComplete="username" />
    <TextField @bind-Value="Model!.Password" AutoComplete="current-password" />
    <Button Submit>Sign in</Button>
</Form>

Sign in with any password: the server turns it down.

Preview

This example turns every password down.

Code

SignIn.razor
@using System.ComponentModel.DataAnnotations

<Form Model="Model" FormName="sign-in" OnValidSubmit="TrySignIn" MaxWidth="24.Rem" Grow>
    @if (_failed)
    {
        <Alert Status="Status.Danger">That email and password don't match. Enter your password again.</Alert>
    }
    <TextField @bind-Value="Model!.Email" AutoComplete="username" />
    <TextField @bind-Value="Model!.Password" AutoComplete="current-password" Hint="This example turns every password down." />
    <Button Submit>Sign in</Button>
</Form>

@code {
    [SupplyParameterFromForm(FormName = "sign-in")]
    private Credentials? Model { get; set; }

    private bool _failed;

    protected override void OnInitialized() => Model ??= new() { Email = "ana@example.com" };

    // A real app checks the password here; this one always fails, to show what comes back.
    private void TrySignIn() => _failed = true;

    public sealed class Credentials
    {
        [Required, EmailAddress]
        public string? Email { get; set; }

        [Required, DataType(DataType.Password)]
        public string? Password { get; set; }
    }
}

Off: After the failed post, the email comes back and the password field is empty.