Form validation message not showing while using partial view

Viewed 3646

I'm working on a ASP.NET core 2.0 application where I created a form to enter data. While checking if the validation works I noticed that there are no validation messages being displayed for a required property of my view model.

When the required input is empty and I press save I can't continue, so the input is required but there is no message to be seen.

The view model for my form view has a list of view models as a property because part of the form has to be changed dynamically.

This is my main view model:

public class SettingsViewModel
{
    public List<KeyValueViewModel> KeyValuePairs { get; set; }
    public string Description { get; set; }
}

Here is the KeyValueViewModel

public class KeyValueViewModel
{
    public int Id { get; set; }
    [Display(Name = "Key")]
    [Required(ErrorMessage = "Key is required")]
    public string Key { get; set; }
    [Display(Name = "Value")]
    [Required(ErrorMessage = "Value is required")]
    public string Value { get; set; }

    public Guid SettingFileId { get; set; }
    public Dictionary<Guid, string> SettingFileDropdownOptions { get; set; }
}

Here is the main view:

@model SettingsViewModel
<form asp-action="Create" id="SettingsForm">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="row">
        <div class="col-md-12">
            <label asp-for="@Model.KeyValuePairs[0].Key" class="control-label col-md-3 no-left-padding"></label>
            <label asp-for="@Model.KeyValuePairs[0].Value" class="control-label col-md-offset-1 no-left-padding"></label>
        </div>
    </div>
    @for (var i = 0; i < Model.KeyValuePairs.Count; i++)
    {
        var keyValuePair = Model.KeyValuePairs[i];
        keyValuePair.Id = i;
        <div id="KeyValuePairsContainer">
            @Html.Partial("_settingKeyValue", keyValuePair)
        </div>
    }
    <div class="form-group col-md-12 no-left-padding">
        <label asp-for="Description" class="control-label"></label>
        <textarea asp-for="Description" class="form-control" ></textarea>
        <span asp-validation-for="Description" class="text-danger"></span>
    </div>
    <div class="form-group col-md-12 no-left-padding">
        <input type="submit" value="Opslaan" class="btn btn-primary" id="Submit" />
        <a href="@Url.Action("Index", "Home")" class="btn btn-default" id="Cancel">Annuleren</a>
    </div>
</form>

And here the partial view that gets rendered:

@model KeyValueViewModel
<div class="form-group col-md-4 no-left-padding">
    <input asp-for="@Model.Key" class="form-control  col-md-3" id="KeyValuePair_Key_@Model.Id" name="KeyValuePairs[@Model.Id].Key" required="required"/>
    <span asp-validation-for="@Model.Key" class="text-danger"></span>
</div>
<div class="form-group col-md-4 no-left-padding">
    <input asp-for="@Model.Value" class="form-control col-md-3" id="KeyValuePair_Value_@Model.Id" name="KeyValuePairs[@Model.Id].Value" required="required" />
    <span asp-validation-for="@Model.Value" class="text-danger"></span>
</div>

The validation message on the Key and Value properties do not get displayed when they should. We tested the Description property of the SettingsViewModel by adding a required tag with a message, and this worked just fine.

How do I get the validation message of the KeyValueViewModel displayed in my main view?

Edit

<span class="text-danger field-validation-valid" data-valmsg-for="Key" data-valmsg-replace="true"></span>

Doesn't get updated to class="field-validation-error" when it should be

2 Answers

For some reason, asp-validation-for does not work, if the input has a name="..." attribute. Removing the name attribute from the input may solve the problem.

This is because asp.net validation itself uses the name attribute and it expects it to match the name of the attribute in asp-for (exactly, including the first capital letter).

asp-validation-for accepts property name

instead of

<span asp-validation-for="@Model.Value" class="text-danger"></span>

should be

<span asp-validation-for="Value" class="text-danger"></span>
Related