C# 反射blazor-获取属性名称+;价值
在我的父组件上,我有以下内容:C# 反射blazor-获取属性名称+;价值,c#,asp.net-core,razor,blazor,C#,Asp.net Core,Razor,Blazor,在我的父组件上,我有以下内容: <TestComponent @bind-Value="testString" /> @code { [MaxLength(10)] private string testString; } 如果Value有一个MaxLength,我怎么能检查我的TestComponent,如果有,我怎么能得到他的值呢?我已经需要检查属性,以使用DisplayName呈现标签,并且必需的向标签添加一个红色*,我不知道怎么做,我试过做这件事的方法,但
<TestComponent @bind-Value="testString" />
@code {
[MaxLength(10)]
private string testString;
}
如果
Value
有一个MaxLength
,我怎么能检查我的TestComponent
,如果有,我怎么能得到他的值呢?我已经需要检查属性,以使用DisplayName
呈现标签,并且必需的向标签添加一个红色*
,我不知道怎么做,我试过做这件事的方法,但现在成功了
但我记得Blazor已经用ValidationMessage
实现了这一点,因为它从属性中获取属性并对其进行验证。。。所以我决定检查它的源代码
挖得很深,我发现这解释了如何做我们需要的
首先,它有一个表达式
参数,在blazor中它是ValidationMessage
的属性,因此我们可以在这里看到,使用绑定值或像Foo=“@Foo”
那样传递它可能是不可能的(如果可能的话,他们可能会这样做),所以我们需要有另一个属性来传递该类型
e、 g
如果您查看memberExpression.Member
并调用GetCustomAttributes
,您将获得我们所需要的全部定制属性
所以现在我们只需要循环自定义属性,然后做任何你想做的事情
下面是一个简化版本,用于获取表达式中返回的属性的CustomAttribute
private IEnumerable GetExpressionCustomAttributes(表达式访问器)
{
var accessorBody=accessor.Body;
//展开对对象的强制转换
if(accessorBody是一元表达式一元表达式
&&unaryExpression.NodeType==ExpressionType.Convert
&&unaryExpression.Type==typeof(对象))
{
accessorBody=unaryExpression.Operator;
}
if(!(accessorBody是MemberExpression MemberExpression))
{
抛出新ArgumentException($“提供的表达式包含不受支持的{accessorBody.GetType().Name})。{nameof(FieldIdentifier)}仅支持对象的简单成员访问器(字段、属性)。”;
}
返回memberExpression.Member.GetCustomAttributes();
}
以你为例,这里是如何解决它的
.剃刀
<TestComponent @bind-Value="testString" Field="(() => testString)" />
@code {
[MaxLength(10)]
private string testString;
}
@代码{
[MaxLength(10)]
私有字符串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();
}
}
@代码{
[参数]公共表达式字段{get;set;}
[参数]公共字符串值{get;set;}
[参数]公共事件回调值已更改{get;set;}
受保护的覆盖无效OnInitialized()
{
base.OnInitialized();
如果(字段!=null)
{
var attrs=GetExpressionCustomAttributes(字段);
foreach(属性中的var attr)
{
if(属性为MaxLengthAttribute MaxLengthAttribute)
{
//用MaxLengtha贡品做你想做的
}
}
}
}
私有IEnumerable GetExpressionCustomAttributes(表达式访问器)
{
var accessorBody=accessor.Body;
//展开对对象的强制转换
if(accessorBody是一元表达式一元表达式
&&unaryExpression.NodeType==ExpressionType.Convert
&&unaryExpression.Type==typeof(对象))
{
accessorBody=unaryExpression.Operator;
}
if(!(accessorBody是MemberExpression MemberExpression))
{
抛出新ArgumentException($“提供的表达式包含不受支持的{accessorBody.GetType().Name})。{nameof(FieldIdentifier)}仅支持对象的简单成员访问器(字段、属性)。”;
}
返回memberExpression.Member.GetCustomAttributes();
}
}
如果只有一个属性,还可以调用memberExpression.Member.GetCustomAttributes帮助函数来获取所需的属性
fieldName = memberExpression.Member.Name;
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;
}
<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();
}
}
[Parameter] public Expression<Func<T>>Field { get; set; }