我无法弄清楚如何突出显示无效字段并显示themested组件的单个验证词。当添加到页面时,相同的代码可以按预期工作,但是当移动到单独的组件时,页面验证符号会显示此组件的错误,但组件本身并未提供任何验证结果。 我进行了广泛的搜索,我只发现了有关复杂模型验证的主题,但没有在嵌套组件中显示验证信息。这表明我可能缺少一些简单的东西,但是我不知道这是什么。 在这里是复制此行为的简化代码。
product.cs
public class Product
{
public int Id { get; set; }
[Required(ErrorMessage = "Added On Date is required")]
public DateTime? AddedOn { get; set; }
[Required(ErrorMessage = "Product Name is required")]
public string Name { get; set; }
public int BrandId { get; set; }
public int ManufacturerId { get; set; }
}
ChildComponent.Razor
<div class="card">
<div class="card-header">
@(new MarkupString(Caption))
</div>
<div class="card-body">
<input type="text" @bind-value=@TextValue />
<ValidationMessage For=@(() => TextValue) />
<input type="datetime-local" @bind-value=@DateValue />
<ValidationMessage For=@(() => DateValue) />
</div>
</div>
@code {
[Parameter]
public string Caption { get; set; }
[Parameter]
public string TextValue { get; set; }
[Parameter]
public DateTime? DateValue { get; set; }
}
-testpage.razor
@page "/test"
<EditForm OnValidSubmit="HandleFormSubmit" Model="@ProductModel">
<DataAnnotationsValidator />
@*ValidationMessages are returned/displayed*@
<div class="card">
<div class="card-header">
Control on the Page
</div>
<div class="card-body">
<input type="text" @[email protected] />
<ValidationMessage For=@(() => ProductModel.Name) />
<input type="datetime-local" @[email protected] />
<ValidationMessage For=@(() => ProductModel.AddedOn) />
</div>
</div>
@*ValidationMessages are NOT returned/displayed*@
<ChildComponent Caption="Nested Component"
[email protected]
[email protected] />
@*ValidationSummary displays errors as expected*@
<ValidationSummary />
<input type="submit" value="Save" class="btn btn-primary" />
</EditForm>
@code {
Product ProductModel = new Product();
private async Task HandleFormSubmit(EditContext context) { }
}
Edit:
通过@Neilw提供的信息,我现在可以更改输入控件的CSS(无效时红色边框,有效时绿色),但是我仍然无法显示无效控件的验证信息。有什么建议吗?
Chris Sainty的这篇文章提供了解决方案。感谢@neilw
分享了链接。 there是按预期工作的更新代码:
product.cs(无更改)
<div class="card">
<div class="card-header">
@(new MarkupString(Caption))
</div>
<div class="card-body">
<input type="text" class="@textFieldCss"
value=@TextValue @oninput="HandleTextInput" />
@foreach (var message in CascadedEditContext?.GetValidationMessages(textFieldId))
{
<div class="validation-message">@message</div>
}
<input type="datetime-local" class="@dateFieldCss"
value=@DateValue @oninput="HandleDateInput" />
@foreach (var message in CascadedEditContext.GetValidationMessages(dateFieldId))
{
<div class="validation-message">@message</div>
}
</div>
</div>
@code {
private FieldIdentifier textFieldId;
private FieldIdentifier dateFieldId;
private string textFieldCss => CascadedEditContext?.FieldCssClass(textFieldId) ?? "";
private string dateFieldCss => CascadedEditContext?.FieldCssClass(dateFieldId) ?? "";
[CascadingParameter]
private EditContext CascadedEditContext { get; set; }
[Parameter]
public EventCallback<string> TextValueChanged { get; set; }
[Parameter]
public EventCallback<DateTime?> DateValueChanged { get; set; }
[Parameter]
public System.Linq.Expressions.Expression<Func<string>> TextValueExpression { get; set; }
[Parameter]
public System.Linq.Expressions.Expression<Func<DateTime?>> DateValueExpression { get; set; }
protected override void OnInitialized()
{
textFieldId = FieldIdentifier.Create(TextValueExpression);
dateFieldId = FieldIdentifier.Create(DateValueExpression);
}
private async Task HandleTextInput(ChangeEventArgs args)
{
await TextValueChanged.InvokeAsync(args.Value.ToString());
CascadedEditContext?.NotifyFieldChanged(textFieldId);
}
private async Task HandleDateInput(ChangeEventArgs args)
{
await DateValueChanged.InvokeAsync(args.Value == null
? null : Convert.ToDateTime(args.Value));
CascadedEditContext?.NotifyFieldChanged(dateFieldId);
}
[Parameter]
public string Caption { get; set; }
[Parameter]
public string TextValue { get; set; }
[Parameter]
public DateTime? DateValue { get; set; }
}
-testpage.razor-注意到组件的属性。
@bind-
result
感谢您分享这个!我整个下午都在工作。创建一个新的现场识别器是我缺少验证重新射击的部分!