2011-06-21 4 views
2

私は私が複数のサーバーにいくつかのプロジェクトのためにいくつかの共通のコードにこれを移動しようとしていますしかしので、これはうまく機能し、正しい値MVCを使用せずにDisplayName属性にアクセスできますか?

public static string ToCsv<TModel>(this List<TModel> list, string delimiter, string lineBreak, string valueWrap, params Expression<Func<TModel, object>>[] expressions) 
{ 
    var sb = new StringBuilder(); 

    var headers = expressions.Select(m => String.Format("{0}{1}{0}", valueWrap, GetPropertyName(m))).ToArray(); 
    sb.Append(String.Format("{0}{1}", String.Join(delimiter, headers), lineBreak)); 

    foreach (var listItem in list) 
    { 
    var values = expressions.Select(m => String.Format("{0}{1}{0}", valueWrap, m.Compile()(listItem))).ToArray(); 
    sb.Append(String.Format("{0}{1}", String.Join(delimiter, values), lineBreak)); 
    } 

    return sb.ToString(); 
} 

にアクセスするには、ラムダ式を使用して一覧するための一般的なCSVビルダーをリファクタリングしていますアクセス。 System.Web.Mvcアセンブリを参照できません

DisplayName属性にアクセスする良い方法はありますか?そうでない場合は、変数名にアクセスしますか?

私の現在の試みは((MemberExpression) expression.Body).Member.Nameにアクセスしますが、値を文字列に変換する必要がある場合は機能しません。

内部クラスでは動作しませんでした属性を反復処理の第二の試みを(つまりはint型を渡すと、暗黙的に変換する)(すなわちmodel =>はmodel.innerClass.property)カップルシンプルなヘルパー関数で

+0

詳細情報:解決策がないと、私は先に進み、 'System.Web.Mvc.ExpressionHelper'を使用しましたが、別の問題が発生しました。 HtmlHelperとViewDataがなければ、プロパティのDisplayName属性は取得されません。何か案は? –

答えて

0

、あなたはすべての参照を排除することができますSystem.Web.Mvcアセンブリに追加します。下の例では、(model => model.member.property)も動作します。

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Linq; 
using System.Linq.Expressions; 
using System.ComponentModel; 
using System.Reflection; 

namespace Test 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      List<Class1> foobars = new List<Class1>(); 
      foobars.Add(new Class1 { Foo = "Hello world!", Bar = -1, Skip = false, Ref = new Class2 { ToBe = true } }); 

      string result = foobars.ToCsv(",", Environment.NewLine, "\"", m => m.Foo, m => m.Bar, m => m.Ref.ToBe); 
     } 

     public class Class1 
     { 
      [DisplayName("Foo Property")] 
      public string Foo { get; set; } 

      public int Bar { get; set; } 

      [DisplayName("Skipped Property")] 
      public bool Skip { get; set; } 

      [DisplayName("Reference")] 
      public Class2 Ref { get; set; } 
     } 

     public class Class2 
     { 
      [DisplayName("To Be or Not To Be")] 
      public bool ToBe { get; set; } 
     } 
    } 

    public static class Extensions 
    { 
     public static string ToCsv<TModel>(this List<TModel> list, string delimiter, string lineBreak, string valueWrap, params Expression<Func<TModel, object>>[] expressions) 
     { 
      var sb = new StringBuilder(); 

      var headers = expressions.Select(m => String.Format("{0}{1}{0}", valueWrap, GetDisplayName(m))).ToArray(); 
      sb.Append(String.Format("{0}{1}", String.Join(delimiter, headers), lineBreak)); 

      foreach (var listItem in list) 
      { 
       var values = expressions.Select(m => String.Format("{0}{1}{0}", valueWrap, m.Compile()(listItem))).ToArray(); 
       sb.Append(String.Format("{0}{1}", String.Join(delimiter, values), lineBreak)); 
      } 

      return sb.ToString(); 
     } 

     // Get DisplayName, otherwise fallback to Name 
     private static string GetDisplayName(LambdaExpression memberReference) 
     { 
      MemberInfo info = GetMemberInfo(memberReference); 
      DisplayNameAttribute displayNameAttr = Attribute.GetCustomAttribute(info, typeof(DisplayNameAttribute)) as DisplayNameAttribute; 
      return (displayNameAttr != null ? displayNameAttr.DisplayName : info.Name); 
     } 

     // Can be swapped for your favourite GetMemberInfo/GetPropertyInfo utility method (there are many out there) 
     // Source: http://blog.baltrinic.com/software-development/dotnet/extension-methods-for-converting-lambda-expression-to-strings 
     private static MemberInfo GetMemberInfo(LambdaExpression memberReference) 
     { 
      MemberExpression memberExpression; 
      var unary = memberReference.Body as UnaryExpression; 
      if (unary != null) 
       //In this case the return type of the property was not object, 
       //so .Net wrapped the expression inside of a unary Convert() 
       //expression that casts it to type object. In this case, the 
       //Operand of the Convert expression has the original expression. 
       memberExpression = unary.Operand as MemberExpression; 
      else 
       //when the property is of type object the body itself is the 
       //correct expression 
       memberExpression = memberReference.Body as MemberExpression; 

      if (memberExpression == null || !(memberExpression.Member is MemberInfo)) 
       throw new ArgumentException("Expression was not of the form 'x => x.member'."); 

      return memberExpression.Member; 
     } 
    } 
} 
+0

ありがとう、私は今日これを試してみます –

+0

これは近いですし、それは正しいパスのおかげで私を導いてくれました! –

関連する問題