【发布时间】:2011-04-18 19:01:18
【问题描述】:
我将 MVC 用于 REST,以便我可以利用 Razor 输出不同的类型。 CSV 是这些输出之一。而不是为每种输入类型编写此模板:
ID,Created,Content
@foreach (var item in Model.TimeData)
{
<text>@item.ID,@item.Created,"@Html.Raw(item.Content.Replace("\"", "\"\""))"</text>
}
我想利用params 和System.Linq.Expressions.Expression 来写这样的东西:
@{
Html.WriteCsv<TimeObject>(Model.TimeData, p => p.ID, p => p.Created, p => p.Content);
}
我开始编写一个通用的HtmlHelper 并很快意识到我遇到了值类型的问题(memberExpression 将为空)。下面的代码试图只写出 CSV 标题(ID、Created、Content),但它只输出“Content”(因为 ID 和 Created 是值类型(int 和 DateTime)。
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);
}
}
}
我尝试将object 替换为dynamic,认为这样可以,但是当我快速观看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; }
}
【问题讨论】:
-
这与您的问题无关,但使用自定义 ActionResult 会更好。你甚至可以在这里使用它:notesfor.net/post/2010/06/28/…
-
你确定值类型是属性吗?也许它们是需要您将其转换为
(FieldInfo)的字段 -
@Talljoe 这是一个选项,但我不希望使用该解决方案所依赖的魔术字符串(对于忽略的字段)。它似乎也不支持复杂对象(如果 CSVUserModel 上有一个用户,其中包含用户名和密码)。
-
@Slaks @Jose 它不起作用... memberExpression 为空。这是我的 TimeObject 类: [DataContract(IsReference = true, Namespace = "urn:test:TimeObject")] public class TimeObject { [DataMember] public long ID { get;放; } [DataMember] 公共字符串内容 { 获取;放; } [DataMember] public DateTime Created { get;放; } }
-
@Langdon,编写自己的内容非常简单,或者您可以在控制器中构建内容并将其传递给 FileResult(它在 mime 类型、可选文件名等方面做正确的事情)。我不相信 Razor 能很好地处理非 HTML。
标签: c# linq generics dynamic c#-4.0