如何从 lambda 表达式中提取自定义 属性 值?

How can extract Custom Property value from lambda expression?

我有以下class定义

Person.cs

class Person {

  [Column("first_name")]
  public string FirstName { get; set; }

  [Column("last_name")]
  public string LastName { get; set; }
}

我写了一个 HTML 帮助程序扩展来从给定实例中提取 ColumnAttribute 值。然而,它并没有像我预期的那样工作。

这是我尝试过的:

Index.cshtml

@model Person
<p>ColumnName is @Html.ColumnNameFor( model => model.FirstName )</p>

HtmlExtensions.cs(public静态class)

public static string ColumnNameFor<T, P>(this HtmlHelper<T> helper, Expression<Func<T, P>> expression)
{
    var name = ExpressionHelper.GetExpressionText(expression);
    var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);

    // this line causes a runtime error:
    //  Sequence contains no elements
    var attr = (ColumnAttribute)metadata.GetType().GetCustomAttributes(typeof(ColumnAttribute), false).First();
            
  return attr.Name;    // ColumnAttribute stores the value in .Name
}

郑重声明,我可以使用 GetCustomAttributes 提取值,前提是我传递了对 属性 的引用,我认为这会使视图中的代码看起来非常不同来自 Html.TextBoxForHtml.DisplayFor 等的内置 ASP MVC 代码

感谢@benuto 的回答,我能够找到如何使用 MemeberExpress 提取任何所需的自定义属性或 属性。我想要答案来帮助别人,所以我做了一个工作示例。请记住,您需要检查对象是否具有自定义 属性,以避免在访问 FirstOrDefault().Name.

时崩溃
 public static string ColumnNameFor<T, P>( this HtmlHelper<T> helper, 
                                           Expression<Func<T, P>> expression)
 {
      var name = ExpressionHelper.GetExpressionText(expression);

      MemberExpression me = expression.Body as MemberExpression;

      var cp = (ColumnAttribute)me
                  .Member
                  .GetCustomAttributes(typeof(ColumnAttribute), false)
                  .FirstOrDefault();

      return (cp == null) ? null : cp.Name;
 }