1

我们正在构建一个为视图模型提供某些结构化类型的类库,例如 InlineImage。

当与@Html.DisplayFor(...) 一起使用时,我需要能够为此类实例定义默认 HTML 输出,基本上...

  • 当 /Views/DisplayTemplates/InlineImage.cshtml 可用时,使用该模板
  • 当不可用时,它应该输出默认值

然而 ...

  • 当我只覆盖该类的 ToString() 时,它给了我正确的输出,但它得到了 HTML 编码

我发现分析 MVC 源代码可以通过将 [DisplayFormat(HtmlEncode = false)] 添加到 CLASS 来禁用编码

但是......该属性不针对类,所以我通过将它包装到我添加到类中的另一个属性来破解它。这很讨厌,但至少有效:)

我的代码目前如下所示:

[AttributeUsage(AttributeTargets.Class)]
class DisableHtmlEncodeAttribute : DisplayFormatAttribute
{
    public DisableHtmlEncodeAttribute()
    {
        HtmlEncode = false;
    }
}

[DisableHtmlEncode]
internal class InlineImage : IInlineImage
{
    public string AltText { get; set; }

    public string Src { get; set; }


    public override string ToString()
    {
        return $"<figure><img src=\"{Src}\" alt=\"{AltText}\"></figure>";
    }
}

它适用于默认显示,但是当文件系统中提供显示模板时,它不会被使用。可能是因为沿途的某些东西因为该数据注释而减少了它。

我已经尝试过其他几种类似的方法:

  • 将第一个属性与 Html 数据注释一起使用
  • 使用带有 Html 数据注释的显示属性
  • 实现 IHtmlString

但是框架似乎只检查类本身的元数据,而不是在这种情况下检查它的属性。并且 IHtmlString 被完全忽略。

我正在寻找如何从类库中为给定类提供默认显示模板的任何提示,只需将标准显示模板放置到视图文件夹即可覆盖该模板。

4

1 回答 1

1

所以事实证明,我比我想象的更接近,并且在最后一次试验中我让它发挥了作用。

这个技巧与我使用 DisableHtmlEncode 属性所做的类似,但使用了 UIHint 属性。这样,您显然可以告诉引擎将显示模板应用于类,并且它比 Format 属性更强。

这是提供默认 HTML 标记功能的最终代码,当 FS 中提供显示模板时,它使用该模板:

[AttributeUsage(AttributeTargets.Class)]
class DisableHtmlEncodeAttribute : DisplayFormatAttribute
{
    public DisableHtmlEncodeAttribute()
    {
        HtmlEncode = false;
    }
}

[AttributeUsage(AttributeTargets.Class)]
class UseDisplayTemplateAttribute : UIHintAttribute
{
    public UseDisplayTemplateAttribute(string uiHint)
        : base(uiHint)
    {
    }
}

[DisableHtmlEncode]
[UseDisplayTemplate("InlineImage")]
internal class InlineImage : IInlineImage
{
    public string AltText { get; set; }

    public string Src { get; set; }

    public override string ToString()
    {
        return $"<figure><img src=\"{Src}\" alt=\"{AltText}\"></figure>";
    }
}

我对这些黑客并不特别自豪,但正如他们所说的“如果它有效,它并不愚蠢”。

如果有人有更好的想法,请分享...

于 2017-06-29T15:09:38.107 回答