代码之家  ›  专栏  ›  技术社区  ›  Ahmad

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

  •  0
  • Ahmad  · 技术社区  · 5 年前

    我有下面的类定义

    人反恐精英

    class Person {
    
      [Column("first_name")]
      public string FirstName { get; set; }
    
      [Column("last_name")]
      public string LastName { get; set; }
    }
    

    我编写了一个HTML助手扩展来提取 ColumnAttribute 来自给定实例的值。然而,它并不像我预期的那样有效。

    以下是我尝试过的:

    指数cshtml

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

    紧张局势加剧。cs(公共静态类)

    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.TextBoxFor Html.DisplayFor

    0 回复  |  直到 5 年前
        1
  •  0
  •   Ahmad    5 年前

    感谢@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;
     }