为自定义类型定义显示模板

本文关键字:显示 定义 自定义 类型 | 更新日期: 2023-09-27 18:34:24

是否可以

在定义属性类型时指定显示模板名称?

例如,我有一些类:

public interface IFoo {}
public class Foo : IFoo {}
public class Bar : IFoo {}

然后我有一个模型:

public class MyModel{
    IFoo IFooExample {get;set;}
}

然后我想在我的视图中渲染IFooExample

@model MyModel
@Html.DisplayFor(x => x.IFooExample)

FooBar可以共享同一个显示模板,即~/Views/Shared/DisplayTemplates/IFoo.cshtml。 如何将此逻辑插入 Mvc,以便我不必 a) 创建Foo.cshtmlBar.cshtml或 b) 从我的视图调用DisplayFor对视图进行重载 (@Html.DisplayFor(x => x.IFooExample, "IFoo.cshtml") )。

我也不想用 UIHint 属性装饰我的模型。我真的很想指定有关FooBar定义的信息:

[UIHint("IFoo.cshtml")]
public class Foo : IFoo{}
[UIHint("IFoo.cshtml")]
public class Bar : IFoo{}

但是UIHint不能在类级别应用。 那么有没有另一种方法可以做到这一点呢?

为自定义类型定义显示模板

你只需要创建一个新的DisplayFor HtmlHelper扩展方法,它特定于接口IFoo,并在其中显示所需的模板。例如:

public static class DisplayForExtensions
{
    public static MvcHtmlString DisplayFor<TModel>(this HtmlHelper<TModel> html,
        Expression<Func<TModel, IFoo>> propertySelector)
    {
        return html.DisplayFor(propertySelector, "IFoo.cshtml");
    }
}

此扩展方法比原始方法更具体,原始方法接受任何类型的值,而不是特定的IFoo属性。

请记住,此扩展方法必须在您的 razor 模板中可见。为此,您可以:

  • 在每个所需的 Razor 模板中包含具有@using的命名空间
  • 将其包含在web.config 中,在 <namespaces> 下创建一个新<add namespace="Your extension class namespace" />,以便它可用于所有 Razor 模板