我已经需要检查属性以使用DisplayName 渲染标签和Required 向标签添加红色*,我不知道该怎么做,我尝试了normal way 这样做,但现在成功了。
但后来我记得 Blazor 已经使用 ValidationMessage 执行此操作,因为它从属性中获取属性并对其进行验证......所以我决定检查它的源代码。
深入挖掘,我找到了this function,它解释了如何做我们需要的事情。
首先,它有一个 Expression<Func<T>> 参数,在 blazor 中是 ValidationMessage 的 For 属性,所以我们可以看到这里可能无法使用绑定值或仅传递它就像Foo="@Foo"(如果可能的话,他们可能会这样做),所以我们需要另一个属性来传递该类型
例如
<TestComponent @bind-Value="testString" Field=@"(() => testString)" />
现在继续该函数的代码,它将获取表达式的Body 并进行一些检查以获取并确保您正在传递一个属性。
然后就是这条线。
fieldName = memberExpression.Member.Name;
如果您查看memberExpression.Member 并调用GetCustomAttributes,您将拥有我们所需要的所有属性的自定义属性。
所以现在我们只需要循环自定义属性并做任何你想做的事情。
这里是获取CustomAttributeExpression<Func<T>>中返回的属性的简化版本
private IEnumerable<CustomAttributeData> GetExpressionCustomAttributes<T>(Expression<Func<T>> accessor)
{
var accessorBody = accessor.Body;
// Unwrap casts to object
if (accessorBody is UnaryExpression unaryExpression
&& unaryExpression.NodeType == ExpressionType.Convert
&& unaryExpression.Type == typeof(object))
{
accessorBody = unaryExpression.Operand;
}
if (!(accessorBody is MemberExpression memberExpression))
{
throw new ArgumentException($"The provided expression contains a {accessorBody.GetType().Name} which is not supported. {nameof(FieldIdentifier)} only supports simple member accessors (fields, properties) of an object.");
}
return memberExpression.Member.GetCustomAttributes();
}
以你为例,这里是如何解决它
.剃刀
<TestComponent @bind-Value="testString" Field="(() => testString)" />
@code {
[MaxLength(10)]
private string testString;
}
TestComponent.razor
<input type="text" @bind="Value" @bind:event="oninput" />
@code {
[Parameter] public Expression<Func<string>>Field { get; set; }
[Parameter] public string Value { get; set; }
[Parameter] public EventCallback<string> ValueChanged { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
if (Field != null)
{
var attrs = GetExpressionCustomAttributes(Field);
foreach (var attr in attrs)
{
if(attr is MaxLengthAttribute maxLengthAttribute)
{
// Do what you want with maxLengthAttribute
}
}
}
}
private IEnumerable<CustomAttributeData> GetExpressionCustomAttributes<T>(Expression<Func<T>> accessor)
{
var accessorBody = accessor.Body;
// Unwrap casts to object
if (accessorBody is UnaryExpression unaryExpression
&& unaryExpression.NodeType == ExpressionType.Convert
&& unaryExpression.Type == typeof(object))
{
accessorBody = unaryExpression.Operand;
}
if (!(accessorBody is MemberExpression memberExpression))
{
throw new ArgumentException($"The provided expression contains a {accessorBody.GetType().Name} which is not supported. {nameof(FieldIdentifier)} only supports simple member accessors (fields, properties) of an object.");
}
return memberExpression.Member.GetCustomAttributes();
}
}
如果您只有一个属性,您也可以调用memberExpression.Member.GetCustomAttributes<Attribute>() 来获取该属性类型的列表。
TL;DR
向组件添加新属性
[Parameter] public Expression<Func<T>>Field { get; set; }
使用this gist 辅助函数来获取你想要的属性。