2011-04-18 73 views
3

我正在使用MVC for REST,以便我可以利用Razor來輸出不同類型的數據。 CSV是其中的一個輸出。而不是寫這個模板爲每個輸入類型:對值類型和引用類型使用C#LINQ表達式

ID,Created,Content 
@foreach (var item in Model.TimeData) 
{ 
<text>@item.ID,@item.Created,"@Html.Raw(item.Content.Replace("\"", "\"\""))"</text> 
} 

我想利用paramsSystem.Linq.Expressions.Expression寫的是這樣的:

@{ 
    Html.WriteCsv<TimeObject>(Model.TimeData, p => p.ID, p => p.Created, p => p.Content); 
} 

我開始寫一個通用的HtmlHelper,並很快意識到我有值類型的問題(memberExpression將爲null)。下面的代碼試圖只寫出來的CSV標題(ID,創建,內容),但它僅輸出「內容」(因爲ID和創建的值類型(intDateTime)。

public static void WriteCsv<TModel>(this HtmlHelper htmlHelper, List<TModel> list, params Expression<Func<TModel, object>>[] expressions) 
{ 
    foreach (var expression in expressions) 
    { 
     MemberExpression memberExpression = expression.Body as MemberExpression; 

     if (memberExpression != null) 
     { 
      var propertyInfo = (PropertyInfo)memberExpression.Member; 

      htmlHelper.ViewContext.Writer.Write(propertyInfo.Name + Environment.NewLine); 
     } 
    } 
} 

我試圖更換objectdynamic,認爲會的工作,但是當我快看expression.Body,似乎仍然認爲它在處理一個對象(DebugView屬性爲(System.Object)$p.ID)。

這是不可能在C#4.0?

下面是我使用它的類型:

[DataContract(IsReference = true, Namespace = "urn:test:TimeObject")] 
public class TimeObject 
{ 
    [DataMember] 
    public long ID { get; set; } 

    [DataMember] 
    public string Content { get; set; } 

    [DataMember] 
    public DateTime Created { get; set; } 
} 
+2

這是切你的問題,但使用自定義的ActionResult會更好。你甚至可以在這裏使用:http://notesfor.net/post/2010/06/28/AspNet-custom-ActionResult-CSV.aspx – Talljoe 2011-04-18 19:05:13

+0

咦?你的代碼應該工作。 – SLaks 2011-04-18 19:05:41

+0

你確定值類型是屬性嗎?也許他們是需要你將字段轉換爲'(FieldInfo)' – Jose 2011-04-18 19:10:46

回答

6

在表達式引用值類型的情況下,編譯器必須裝入引用;它隱含地這樣做。這種複雜性意味着值類型成員表達式的表達式樹不僅僅是一個MemberExpression,所以你的轉換返回null。

下面是從一個值類型或引用類型成員的表達,從this question所獲得的屬性名稱的通用解決方案:

private string GetPropertyName(Expression<Func<object, object>> f) { 
    var body = f.Body; 
    if (body.NodeType==ExpressionType.Convert) 
     body = ((UnaryExpression) body).Operand; 
    if ((body as MemberExpression) != null) { 
     return (body as MemberExpression).Member.Name; 
    } 
    return ""; 
}