yTo*_*ide 8 c# razor asp.net-core blazor
在我的父组件上我有这个:
<TestComponent @bind-Value="testString" />
@code {
[MaxLength(10)]
private string testString;
}
Run Code Online (Sandbox Code Playgroud)
关于我的TestComponent这个:
<input type="text" @bind="Value" @bind:event="oninput" />
@code {
[Parameter] public string Value { get; set; }
[Parameter] public EventCallback<string> ValueChanged { get; set; }
protected override void OnInitialized() {
//Get MaxLength here
}
}
Run Code Online (Sandbox Code Playgroud)
我如何检查我的TestComponentifValue有 aMaxLength并获取他的值(如果有)?
我已经需要检查用于DisplayName渲染标签的属性并向标签Required添加红色*,但我不知道如何执行此操作,我尝试了正常的方法,但没有成功。
但后来我想起 Blazor 已经这样做了ValidationMessage,因为它从属性获取属性并验证它......所以我决定检查它的源代码。
深入挖掘后,我发现这个函数解释了如何做我们需要的事情。
首先,它有一个Expression<Func<T>>参数,在 blazor 中是 的For属性ValidationMessage,所以我们可以在这里看到,可能不可能使用绑定值来做到这一点,或者只是像这样传递它Foo="@Foo"(如果可能的话,他们可能会这样做),所以我们需要另一个属性来传递该类型
例如
<TestComponent @bind-Value="testString" Field=@"(() => testString)" />
Run Code Online (Sandbox Code Playgroud)
现在继续该函数的代码,它将获取Body表达式的 并进行一些检查以获取并确保您正在传递属性。
然后就是这一行。
fieldName = memberExpression.Member.Name;
Run Code Online (Sandbox Code Playgroud)
如果您查看memberExpression.Member并致电,GetCustomAttributes您将获得我们所需要的内容,即该属性的所有自定义属性。
所以现在我们需要的只是循环自定义属性并做你想做的事情。
这是一个简化版本,用于获取CustomAttribute返回的属性Expression<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();
}
Run Code Online (Sandbox Code Playgroud)
以您为例,这是解决方法
。剃刀
<TestComponent @bind-Value="testString" Field="(() => testString)" />
@code {
[MaxLength(10)]
private string testString;
}
Run Code Online (Sandbox Code Playgroud)
测试组件.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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您只有一个属性,您还可以调用memberExpression.Member.GetCustomAttributes<Attribute>()以获取该属性类型的列表。
长话短说
向组件添加新属性
[Parameter] public Expression<Func<T>>Field { get; set; }
Run Code Online (Sandbox Code Playgroud)
使用此 gist辅助函数来获取您想要的属性。