I have a Blazor component called EditOffice. It looks as follows:
<EditForm Model="@Office" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <InputTextRow Label="Name" @bind-Value="@Office.Name" Placeholder="Enter name" />
    <InputTextRow Label="ABN" @bind-Value="@Office.ABN" Placeholder="Enter ABN" />
...
    <button type="submit" class="btn btn-primary edit-btn">Save office</button>
</EditForm>
I created child components called InputTextRow in an attempt to Tidy my code. They look as follows:
<div class="form-group row">
    <label for="@Id" class="col-sm-3">@Label: </label>
    <InputText id="@Id" @oninput="OnValueChanged" @bind-Value="@Value" class="form-control col-sm-8" placeholder="@Placeholder"></InputText>
    <ValidationMessage class="offset-sm-3 col-sm-8" For="@(() => Value)" />
</div>
@code {
    public string Id => Label.ToLower().Replace(" ", "");
    [Parameter]
    public string Label { get; set; }
    [Parameter]
    public string Value { get; set; }
    [Parameter]
    public string Placeholder { get; set; }
    [Parameter] public EventCallback<string> ValueChanged { get; set; }
    Task OnValueChanged(ChangeEventArgs e)
    {
        Value = e.Value.ToString();
        return ValueChanged.InvokeAsync(Value);
    }
}
The ValidationMessage doesn't work when in my child component. Any idea why?
I know I'm a little late but here is my answer :)
So there is better solution right now.
Be advised - it's experimental, but package is already in release candidate so no worries I guess.
Use Microsoft.AspNetCore.Components.DataAnnotations.Validation package and <ObjectGraphDataAnnotationsValidator /> instead of <DataAnnotationsValidator /> and use this thingy:
using System.ComponentModel.DataAnnotations;
public class YourComplexModel
{
    // other properties
    [ValidateComplexType] // <--life saver
    public ChildModel ChildModel { get; set; } = new ChildModel();
}
Link Microsoft Docs:
Blazor provides support for validating form input using data annotations with the built-in DataAnnotationsValidator. However, the DataAnnotationsValidator only validates top-level properties of the model bound to the form that aren't collection- or complex-type properties.
To validate the bound model's entire object graph, including collection- and complex-type properties, use the ObjectGraphDataAnnotationsValidator provided by the experimental Microsoft.AspNetCore.Components.DataAnnotations.Validation package:
<EditForm Model="@model" OnValidSubmit="@HandleValidSubmit">
    <ObjectGraphDataAnnotationsValidator />
    ...
</EditForm>
Annotate model properties with [ValidateComplexType]. In the following model classes, the ShipDescription class contains additional data annotations to validate when the model is bound to the form:
Starship.cs:
using System;
using System.ComponentModel.DataAnnotations;
public class Starship
{
    ...
    [ValidateComplexType]
    public ShipDescription ShipDescription { get; set; } = 
        new ShipDescription();
    ...
}
ShipDescription.cs:
using System;
using System.ComponentModel.DataAnnotations;
public class ShipDescription
{
    [Required]
    [StringLength(40, ErrorMessage = "Description too long (40 char).")]
    public string ShortDescription { get; set; }
    [Required]
    [StringLength(240, ErrorMessage = "Description too long (240 char).")]
    public string LongDescription { get; set; }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With