带有通用类的Html.DisplayFor

时间:2013-08-06 18:55:21

标签: asp.net-mvc

我有一个这样的类,有一个泛型:

Document<T>

此类是视图模型的一部分

public class MyViewModel
{
   public IEnumerable<Document<T>> Documents {get;set;}

}

我想使用DisplayFor调度到view.cshtml中的相应模板

@model MyViewModel
foreach(var vm in Model.Documents)
{
   @Html.DisplayFor(vm)
}

但我不知道如何在具有类名称的Shared / DisplayTemplates中创建模板,但C#名称省略了通用参数:

 Document`1

但这是不够的,因为它没有识别完整的类型结构。

有没有办法将DisplayFor与DisplayTemplates和Generic Types一起使用?

1 个答案:

答案 0 :(得分:5)

您可以这样做:

@foreach(var vm in Model.Documents)
{
    Type type = vm.GetType().GetGenericArguments()[0];
    var templateName = "Document_" + type.Name;
    @Html.DisplayFor(model => vm, templateName)
}

然后,您的DisplayTemplates将被命名为“Docuement_Entity1.cshtml”,“Document_Entity2.cshtml”,......其中Entity1和Entity2是您的通用参数类型。

或者,您可以为Document类创建一个TemplateName属性,就像在上面的代码中一样设置它,并在View中使用它,如下所示:

@foreach(var vm in Model.Documents)
{
    @Html.DisplayFor(model => vm, vm.TemplateName)
}

<强>更新

如果你想使用Html Helper,你可以这样做:

public static MvcHtmlString DisplayGenericFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
{
    var modelType = helper.ViewData.Model.GetType();
    if (!modelType.IsGenericType)
        throw new ArgumentException();

    Type genericType = modelType.GetGenericArguments()[0];
    var templateName = modelType.Name.Split('`').First() + "_" + genericType.Name;
    return helper.DisplayFor<TModel, TValue>(expression, templateName);      
}