0
votes

I'm having issues with Model Validation. It doesn't show any errors when the ModelState contains errors. It sets focus to the first textbox (Firstname), but no visible error message.

Model, CreateSiteUserModel:

public interface ICreateSiteUserModel
{
    [Required]
    Guid SiteUId { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "Skriv inn fornavn")]
    string Firstname { get; set; }

    [Required(ErrorMessage = "Skriv inn etternavn")]
    string Lastname { get; set; }

    [Required(ErrorMessage = "Skriv inn emailadresse")]
    [EmailAddress]
    string Email { get; set; }

    [Required(ErrorMessage = "Skriv inn passord")]
    [StringLength(30, MinimumLength = 8, ErrorMessage = "Passordet må bestå av minst 8 tegn inkludert minst et tall")]
    string Password { get; set; }
}

public class CreateSiteUserModel : ICreateSiteUserModel
{
    public Guid SiteUId { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
}

Model, SiteModel:

public interface ISiteModel
{
    ISiteWrapper Site { get; set; }
    ICreateSiteUserModel SiteUserModel { get; set; }
}

public class SiteModel : ISiteModel
{
    public ISiteWrapper Site { get; set; }
    public ICreateSiteUserModel SiteUserModel { get; set; } = new CreateSiteUserModel();
}

Controller:

[HttpPost]
public async Task<IActionResult> Site([FromForm] CreateSiteUserModel model)
{
    IActionResult action = default;
    ISite site = await _sites.GetSite(model.SiteUId);

    if (this.ModelState.IsValid)
    {
        IdentityResult result = await _ident.CreateUser(site.Id, model.Email, model.Password);

        if (result.Succeeded)
        {
            IUser user = await this.DB.GetWorker<User>().Latest();

            action = RedirectToAction("EditSiteUser", "Identity", new { UId = user.UId });
        }
    }
    else
    {
        ISiteModel mdl = new SiteModel() { Site = new SiteWrapper(site, this.DB), SiteUserModel = model };

        action = View(mdl);
    }

    return action;
}

CSHTML:

@model ISiteModel

<form method="post">
    <table style="width:100%;">
        <tr>
            <td style="width:140px;">
                <label asp-for="SiteUserModel.Firstname"></label>
            </td>
            <td>
                <input id="firstname" name="firstname" type="text" class="txt-light" asp-for="SiteUserModel.Firstname" />
                <span class="error-msg color-danger" asp-validation-for="SiteUserModel.Firstname"></span>
            </td>
        </tr>
        <tr>
            <td>Etternavn</td>
            <td>
                <input id="lastname" name="lastname" type="text" class="txt-light lastname" />
            </td>
        </tr>
        <tr>
            <td>Email</td>
            <td>
                <input id="email" name="email" type="email" class="txt-light email" />
            </td>
        </tr>
        <tr>
            <td>Passord</td>
            <td>
                <input id="password" name="password" type="text" class="txt-light password" />
            </td>
        </tr>
        <tr>
            <td></td>
            <td class="pad-md">
                <input id="siteUId" name="siteUId" type="hidden" value="@site.UId" />
                <input type="submit" class="btn-dark" value="Lagre" formmethod="post" />
            </td>
        </tr>
    </table>
</form>

HTML after submit:

<form method="post" novalidate="novalidate">
    <table style="width:100%;">
        <tbody>
            <tr>
                <td style="width:140px;">
                    <label for="SiteUserModel_Firstname">Firstname</label>
                </td>
                <td>
                    <input id="firstname" name="firstname" type="text" class="txt-light firstname input-validation-error" data-val="true" data-val-required="Skriv inn fornavn" value="" aria-describedby="firstname-error" aria-invalid="true">
                    <span class="error-msg color-danger field-validation-valid" data-valmsg-for="SiteUserModel.Firstname" data-valmsg-replace="true"></span>
                </td>
            </tr>
            <tr>
                <td>Etternavn</td>
                <td>
                    <input id="lastname" name="lastname" type="text" class="txt-light lastname">
                </td>
            </tr>
            <tr>
                <td>Email</td>
                <td>
                    <input id="email" name="email" type="email" class="txt-light email valid">
                </td>
            </tr>
            <tr>
                <td>Passord</td>
                <td>
                    <input id="password" name="password" type="text" class="txt-light password">
                </td>
            </tr>
            <tr>
                <td></td>
                <td class="pad-md">
                    <input id="siteUId" name="siteUId" type="hidden" value="62e8a8b1-72be-4f71-b2e6-9dce89fcde76">
                    <input type="submit" class="btn-dark" value="Lagre" formmethod="post">
                </td>
            </tr>
        </tbody>
    </table>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8JxeOiw3r2BBtI-MX6Hqs7u_pj2MJEQMl0kZvyoVW0CicaRoZns_U7UnOIrDe0ADt2mVHvxhOPagANjX4C0QupCPvRaKyz8YRnwOaK64gNIisfzv1ii_HRMrXS2Hpd_L9bHm6ypzgyyE-v7029xP_kg">
</form>
1
I expect this is because you specify id and name attributes for your inputs. These override the one's set by using asp-for - just use the generated ones. - Kirk Larkin
@KirkLarkin yes you're right - removed id and name and it worked. thanks! - SteinTheRuler
No worries. You can see the problem in your rendered HTML. You've got name as firstname but data-valmsg-for etc are for SiteUserModel.Firstname. These don't match, so the validation message doesn't know what to do. - Kirk Larkin

1 Answers

0
votes

As @KirkLarkin suggested: remove Id and Name attributes - let helper generate values.

HTML:

<tr>
    <td style="width:140px;">
        <label asp-for="SiteUserModel.Firstname"></label>
    </td>
    <td>
        <input type="text" class="txt-light firstname" asp-for="SiteUserModel.Firstname" />
        <span class="error-msg color-danger" asp-validation-for="SiteUserModel.Firstname"></span>
    </td>
</tr>