c# - 从 Lambda 属性表达式获取自定义属性

标签 c# attributes lambda

我正在使用 ASP.NET MVC 2 Preview 2 并编写了自定义 HtmlHelper 扩展方法来使用表达式创建标签。 TModel 来自具有属性的简单类,并且属性可能具有定义验证要求的属性。我试图找出表达式在我的标签方法中表示的属性上是否存在某个属性。

类和标签的代码是:

public class MyViewModel
{
    [Required]
    public string MyProperty { get; set; }
}

public static MvcHtmlString Label<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string label)
{
    return MvcHtmlString.Create(string.Concat("<label for=\"", expression.GetInputName(), "\">", label, "</label>"));
}

public static string GetInputName<TModel, TProperty>(this Expression<Func<TModel, TProperty>> expression)
{
    return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
}

然后我会这样称呼标签:

Html.Label(x => x.MyProperty, "My Label")

有没有办法找出传递给 Label 方法的表达式值中的属性是否具有 Required 属性?

我发现执行以下操作确实可以获得属性(如果存在),但我希望有一种更简洁的方法来完成此操作。

public static MvcHtmlString Label<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string label)
{
    System.Attribute.GetCustomAttribute(Expression.Property(Expression.Parameter(expression.Parameters[0].Type, expression.GetInputName()), expression.GetInputName()).Member, typeof(RequiredAttribute))

    return MvcHtmlString.Create(string.Concat("<label for=\"", expression.GetInputName(), "\">", label, "</label>"));
}

最佳答案

您的表达式解析逻辑可能需要一些工作。您不是在处理实际类型,而是在转换为字符串。

这是一组您可以改用的扩展方法。第一个获取成员的名称。第二个/第三个结合起来检查属性是否在成员上。 GetAttribute 将返回请求的属性或 null,而 IsRequired 仅检查该特定属性。

public static class ExpressionHelpers
{
    public static string MemberName<T, V>(this Expression<Func<T, V>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression == null)
            throw new InvalidOperationException("Expression must be a member expression");

        return memberExpression.Member.Name;
    }

    public static T GetAttribute<T>(this ICustomAttributeProvider provider) 
        where T : Attribute
    {
        var attributes = provider.GetCustomAttributes(typeof(T), true);
        return attributes.Length > 0 ? attributes[0] as T : null;
    }

    public static bool IsRequired<T, V>(this Expression<Func<T, V>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression == null)
            throw new InvalidOperationException("Expression must be a member expression");

        return memberExpression.Member.GetAttribute<RequiredAttribute>() != null;
    }
}

希望这对您有所帮助。

关于c# - 从 Lambda 属性表达式获取自定义属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1559800/

相关文章:

c# - WPF 自定义 ChartLine 性能问题

Magento - 属性 "input-type"复选框

c# - 使用自定义属性获取其成员之一的类

C# - 禁用动态关键字

c# - 添加特定对象的新记录时 Entity Framework 5 失败

c# - 在 Windows 中使用 Java 或 C# 添加自定义文件属性/属性

java - 如何在 Java 中映射 lambda 表达式

c# - LINQ to Entities 中的 Enum.HasFlag?

c# - 从字符串构造嵌套属性的 LambdaExpression

c# - 将 NameValueCollection 转换为动态对象