Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反射blazor-获取属性名称+;价值_C#_Asp.net Core_Razor_Blazor - Fatal编程技术网

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; }