c# - 如何设置 ValidationMessage.对于 Blazor 中的动态属性?
问题描述
文档的这一部分描述了如何显示验证消息。
<ValidationMessage For="() => Parameters.PropertyA"></ValidationMessage>
如何动态设置 ValidationMessage.For 属性?
由于For
是 type Expression<Func<TValue>>
,我想传递一个 Func ,但这不会编译:
[Parameter]
public Func<string> PropertyLocator { get; set; }
<ValidationMessage For="PropertyLocator"></ValidationMessage>
这会编译,但验证消息将无法正确解析
<ValidationMessage For="() => PropertyLocator"></ValidationMessage>
我还尝试使组件通用,以便它知道Parameters
类型:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Components;
public partial class MyComponent<TParam>
{
[Parameter]
public TParam Parameters { get; set; }
[Parameter]
public Func<TReportParam, string> PropertyLocator { get; set; }
}
@using System.Linq.Expressions
@typeparam TParam
<ValidationMessage For="@((Expression<Func<string>>)(() => PropertyLocator(this.Parameters)))"></ValidationMessage>
<MyComponent TParam="MyParameters" Parameters="BindToSomeValue" PropertyLocator="(parameters) => parameters.PropertyA" />
但这会导致以下运行时异常:
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常呈现组件:提供的表达式包含不受支持的 InvocationExpression1。FieldIdentifier 仅支持对象的简单成员访问器(字段、属性)。System.ArgumentException:提供的表达式包含不受支持的 InvocationExpression1。FieldIdentifier 仅支持对象的简单成员访问器(字段、属性)。在 Microsoft.AspNetCore.Components.Forms.FieldIdentifier.Create[String](Expression`1 访问器) 在 Microsoft.AspNetCore.Components.Forms.FieldIdentifier.ParseAccessor[String](Expression`1 accessor, Object& model, String& fieldName) .AspNetCore.Components.Forms.ValidationMessage`1[[System.String, System.Private.CoreLib, 版本=5.0.0.0,
解决方案
我创建了一个小示例页面。
该模型DataAnnotations
用作验证机制。
public class DemoInputModel
{
[Required]
public String PropertyOne { get; set; }
[MinLength(2)]
public String PropertyTwo { get; set; }
[MaxLength(5)]
public String PropertyThree { get; set; }
}
在页面上,模型被初始化并设置为编辑上下文。我们有三个文本输入和一个选择框。选择框可用于切换验证消息。如果更改了选择框的值,则将新表达式分配给ValidationMessage
.
@using System.ComponentModel.DataAnnotations;
@using System.Linq.Expressions;
@page "/test"
<h1>ValidationMessageTest</h1>
<EditForm Model="_model">
<DataAnnotationsValidator />
<ValidationMessage For="ValidationResolver"></ValidationMessage>
<InputText @bind-Value="_model.PropertyOne" />
<InputText @bind-Value="_model.PropertyTwo" />
<InputText @bind-Value="_model.PropertyThree" />
<InputSelect @bind-Value="SelectedValidationProperty">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</InputSelect>
@*<ValidationSummary />*@
</EditForm>
@code {
private DemoInputModel _model = new DemoInputModel
{
PropertyOne = "Test",
PropertyTwo = "42",
PropertyThree = "Math.PI",
};
private String _selectedValidationProperty;
public String SelectedValidationProperty
{
get => _selectedValidationProperty;
set
{
_selectedValidationProperty = value;
ChangeValidator(value);
}
}
public Expression<Func<String>> ValidationResolver { get; set; }
protected override void OnInitialized()
{
SelectedValidationProperty = "1";
base.OnInitialized();
}
public void ChangeValidator(String value)
{
switch (value)
{
case "1":
ValidationResolver = () => _model.PropertyOne;
break;
case "2":
ValidationResolver = () => _model.PropertyTwo;
break;
case "3":
ValidationResolver = () => _model.PropertyThree;
break;
default:
break;
}
}
}
你的意思是这样的吗?如果你的模型不只有字符串,它会稍微复杂一些,就像例子中一样。一个“快速”的解决方法可能是Expression
为每种可能的类型设置一个。
在引擎盖下,表达式用于创建一个FieldIdentifier
. 然后 FieldIdentifier
用于从 获取相应的属性/字段EditContext
以检查验证状态。因此,您在为表达式选择什么方面受到限制。错误消息FieldIdentifier 仅支持对象的简单成员访问器(字段、属性)很好地表明了此限制。
推荐阅读
- c# - 如何在 C# 的同一行中打印字典键和该键的倍数值
- fullcalendar - 将您的应用日历与 google/outlook 日历同步
- jquery - 当 jQuery UI datetimepicker 关闭并且日期/时间更改时运行 AJAX
- javascript - Redux Store 未在 Chrome 扩展程序中连接
- python - 将 DataFrame 转换为对象数组
- node.js - 一个rest api可以是IP地址吗?还是必须是网址?
- javascript - 如何摆脱/覆盖剑道上的添加行弹出标题?
- javascript - 使用 js 从 html 发送数据并使用 gson 在 servlet 上发送数据
- java - 如何打印字符串数组列表?
- r - geom_line 上方 geom_segment 的类似热图的图例