带有通用类的Html.DisplayFor

Dou*_*oug 4 asp.net-mvc

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

Document<T>

此类是视图模型的一部分

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

}
Run Code Online (Sandbox Code Playgroud)

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

@model MyViewModel
foreach(var vm in Model.Documents)
{
   @Html.DisplayFor(vm)
}
Run Code Online (Sandbox Code Playgroud)

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

 Document`1
Run Code Online (Sandbox Code Playgroud)

但这是不足够的,因为它不能识别完整的类型结构.

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

ata*_*ati 6

你可以这样做:

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

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

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

@foreach(var vm in Model.Documents)
{
    @Html.DisplayFor(model => vm, vm.TemplateName)
}
Run Code Online (Sandbox Code Playgroud)

更新:

如果你想使用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);      
}
Run Code Online (Sandbox Code Playgroud)