【问题标题】:Inserting line breaks in DisplayName attributes在 DisplayName 属性中插入换行符
【发布时间】:2023-03-31 22:30:01
【问题描述】:

在我的 ViewModel 中有一个需要 2 行标签的属性,但是当我在 DisplayName 属性中放置 <br /> 时,HTML 代码会打印到页面上,而不是被解释为换行符。有没有办法让DisplayName 在其中换行?

查看:

    <tr>
        <td>
            @Html.LabelFor(m => m.GrossGallons)
        </td>
        <td>
        </td>
    </tr>

视图模型:

    [DisplayName("Gross Gallons <br /> (Max: 6,000)")]
    public decimal GrossGallons { get; set; }

试图获取的输出:

Gross Gallons
(Max: 6,000)

【问题讨论】:

  • 你在用@Html.EditorFor(...)吗?
  • 是的,我正在使用@Html.EditorFor() 来显示输入选项。
  • @MatthewVerstraete - 在此处查看 Darins 的答案 - stackoverflow.com/questions/10478454/…。基本上,在不求助于黑客的情况下,您应该制作自己的标签来创建 Html 助手,以便您可以渲染出未编码的 Html。我会简单地在任何地方使用它来代替标准的 Html.LabelFor,这样您就不必跟踪哪些标签有 html 而哪些没有

标签: asp.net-mvc asp.net-mvc-viewmodel


【解决方案1】:

有一种简单的方法 - 使用 \n 而不是 &lt;br /&gt;,并使用 CSS 使其工作。

型号:

[DisplayName("Gross Gallons\n(Max: 6,000)")]
public decimal GrossGallons { get; set; }

CSS:

label { white-space: pre-wrap; }

我建议使 CSS 选择器尽可能具体,以免捕捉到其他标签(如果您在其他地方手动使用标签,您的源代码可能包含空格)。例如,在引导程序中,我会将其应用于label.control-label

您还可以仅将更具体的样式附加到该标签,并仅设置该类的样式。

@Html.LabelFor(m => m.GrossGallons, new { @class = "multiline-label" })

【讨论】:

  • 这很简单!谢谢!
【解决方案2】:

我能想到几个选项。

1) 你可以使用@Html.Raw()。您可以将我输入的字符串替换为对字符串的引用。

@Html.Raw("Gross Gallons <br /> (Max: 6,000)");

1a) 如果您需要在 DisplayName 属性中设置它,那么您可以尝试使用 Html.Raw() 但通过反射访问该值。 (注:这个我没试过,不知道有没有可能)

2) 您可以使用 css 样式来强制换行到您想要的位置。

3) 您可以创建自定义扩展方法或自定义属性来为您执行此操作。

【讨论】:

  • 1:这会破坏使用@Html.LabelFor 的目的。 2:我真的认为使用 CSS hack 既不高效也不合适。 3:我曾考虑过自定义扩展,但我希望可能有更简单的 MVC 解决方案。
【解决方案3】:

你可以使用@Html.Raw(),我认为这是最简单的方法。

【讨论】:

  • 这会破坏使用@Html.LabelFor的目的。
  • @Html.LabelFor 不是 @Html.Raw()
  • @Html.LabelFor 是
  • 我知道 HTML 助手之间的区别。在我的示例中,我使用了@Html.LabelFor(),因为我希望代码生成&lt;label /&gt; 标记。首先使用@Html.Raw 会破坏使用@Html.LabelFor() 的全部原因。我什至不确定您是否可以传入模型并获取 DisaplyName 属性以由 @Html.Raw 助手解析。
【解决方案4】:

它并不漂亮,但您可以使用EditorTemplates 并创建一个所有模板都使用的_layout.cshtml。然后用它来拉/显示DisplayName:

<div class="form-group">
    <label for="@ViewData.ModelMetadata.PropertyName">
        @Html.Raw(ViewData.ModelMetadata.GetDisplayName())
    </label>
    @RenderBody()
    @Html.ValidationMessageFor(x => x)
</div>

这样做的严重缺点是您必须为每个类型创建 EditorTemplates,例如此示例 string.cshtml 模板:

@model string
@{
    Layout = "_Layout.cshtml";
}
@Html.TextBoxFor(x => x, new { @class="form-control" })

有点跑题了,但是走这条路可以让我在表单元素周围封装包装 HTML,所以视图中的表单最终非常简单,如下所示:

<fieldset>
  @Html.EditorFor(x => x.Email)
  @Html.EditorFor(x => x.Address1)
  @Html.EditorFor(x => x.Address2)
  @Html.EditorFor(x => x.City)
</fieldset>

【讨论】:

  • 为什么要将标签和验证消息放在布局页面中,而不是正好在所有其他表单标记所在的页面中?
  • 因为我只需要在那里做一次,而其他地方每次都要做。 @Html.EditorFor() 为我解决了这个问题。
  • 再一次,它并不漂亮。 :-) 我不喜欢内置的 EditorFor 模板,所以我通常最终都会为所有类型编写自己的模板。因此这对我来说不是问题,但是如果你对内置的很好,那么还有很多额外的工作......
  • 但是将它放在布局模板中会搞砸不显示表单数据或任何使用不具有DisplayPropery 属性的模型的表单数据的页面,对吧?
  • 是和否,如果您使用 EditorFor,它会放入 Layout 的东西。我只在标准表单中使用 EditorFor。如果不使用 DisplayName 属性,GetDisplayName() 将返回 PropertyName
【解决方案5】:

如果使用LabelFor(),另一个“可能”的解决方案是使用original source 作为指导来实现您自己的解决方案。

替换

tag.SetInnerText(resolvedLabelText);

tag.InnerHtml = resolvedLabelText;

【讨论】:

  • 不知道这将如何与EditorFor 一起工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
  • 2010-11-06
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
相关资源
最近更新 更多