【问题标题】:How to make Html.DisplayFor display line breaks?如何使 Html.DisplayFor 显示换行符?
【发布时间】:2012-02-20 07:01:39
【问题描述】:

令人尴尬的新手问题:

我的模型中有一个 string 字段,其中包含换行符。

@Html.DisplayFor(x => x.MultiLineText)

不显示换行符。

显然我可以在模型中做一些摆弄,并创建另一个字段,用<br/> 替换\n,但这看起来很笨拙。完成这项工作的教科书方法是什么?

【问题讨论】:

标签: asp.net-mvc-3 razor


【解决方案1】:

尝试使用
@Html.Raw("<p>" + Html.LabelFor(x => x.Name) + "</p>")

【讨论】:

    【解决方案2】:

    您为您的数据创建一个显示模板。 这是一篇详细说明如何操作的帖子。 How do I create a MVC Razor template for DisplayFor()

    在该模板中,您可以将换行符实际翻译成
    以及任何其他需要进行演示的工作。

    【讨论】:

    • +1 表示模板的想法,但答案归功于@slapthelownote 给出的实际实现
    【解决方案3】:

    在您看来,您可以尝试类似的方法

    @Html.Raw(Html.Encode(Model.MultiLineText).Replace("\n", "<br />"))
    

    【讨论】:

    • 至少应该是.Replace("\r\n", ...)。此外,在我看来,下面的solution from cwills 要好得多。
    • 没有 \n 真的足够了:剩余的 \r 不会有害,因为它们只是 html 的空白。在 \r\n 上匹配时会错过 unix 样式的换行符并且不会处理它们。
    • 不确定是不是因为我使用ViewData而不是常规属性,但是在ASP.NET Core Razor中,我不得不使用@Html.Raw(((string)ViewData["MyText"]).Replace("\n", "&lt;br /&gt;"))
    • 我使用了一种稍微不同的方法,我的案例中存储的数据是 SQL 文本:@Html.Raw(field.Replace("\n", "&lt;br /&gt;"))
    【解决方案4】:

    显示模板可能是最好的解决方案,但如果你知道你只是显示一个字符串,还有另一个简单的选择是使用 html 帮助器,例如:

    namespace Shaul.Web.Helpers
    {
        public static class HtmlHelpers
        {
            public static IHtmlString ReplaceBreaks(this HtmlHelper helper, string str)
            {
                return MvcHtmlString.Create(str.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None).Aggregate((a, b) => a + "<br />" + b));
            }
        }
    }
    

    然后你会像这样使用它:

    @using Shaul.Web.Helpers
    
    @Html.ReplaceBreaks(Model.MultiLineText)
    

    【讨论】:

      【解决方案5】:

      一个 HtmlHelper 扩展方法来显示带有换行符的字符串值:

      public static MvcHtmlString DisplayWithBreaksFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
      {
          var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
          var model = html.Encode(metadata.Model).Replace("\r\n", "<br />\r\n");
      
          if (String.IsNullOrEmpty(model))
              return MvcHtmlString.Empty;
      
          return MvcHtmlString.Create(model);
      }
      

      然后你可以使用下面的语法:

      @Html.DisplayWithBreaksFor(m => m.MultiLineField)
      

      【讨论】:

      • 在 MVC 4 中哪里可以定义它?
      • 很好,但是当值为 null 或为空时,我不会返回 MvcHtmlString.Empty,而是调用标准的 HtmlHelper.DisplayFor 方法,以便可以使用任何 NullDisplayText 装饰。
      • 对于其他可能不知道的新手,在“public static class HtmlExtensions { }”中定义cwills的DisplayWithBreaksFor()方法
      • 使用DisplayTemplate 而不是引入HtmlHelper 方法的优势在于,它可以细化到未明确定义的属性和视图(请参阅my answer)。
      【解决方案6】:

      我建议使用 css 格式化输出,而不是使用 cpu 消耗服务器端字符串操作,如 .replace,

      只需添加此样式属性即可呈现多行文本:

      .multiline
      {
         white-space: pre-wrap;
      }
      

      然后

      <div class="multiline">
        my
        multiline
        text
      </div>
      

      newlines 会像 br 元素一样渲染,在这里测试一下https://snippet.run/xaf4

      【讨论】:

      • 要对此进行改进,以便 Html.DisplayFor 仍然可以使用,请将 [System.ComponentModel.DataAnnotations.DataType(System.ComponentModel.DataAnnotations.DataType.MultilineText)] 属性应用于模型上的 MultiLineText 属性,并使用内容 @model string &lt;span class="multiline"&gt;@Model&lt;/span&gt; 创建一个 DisplayTemplate
      • 这可能已经不重要了,但这在IE9及以下版本中不起作用
      【解决方案7】:

      这是另一个扩展方法选项。

          public static IHtmlString DisplayFormattedFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, string>> expression)
          {
              string value = Convert.ToString(ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model);
      
              if (string.IsNullOrWhiteSpace(value))
              {
                  return MvcHtmlString.Empty;
              }
      
              value = string.Join("<br/>", value.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Select(HttpUtility.HtmlEncode));
      
              return new HtmlString(value);
          }
      

      【讨论】:

        【解决方案8】:

        灵感来自DisplayTemplates for common DataTypes, 我覆盖(引入?)DataType.MultilineText/Views/Shared/DisplayTemplates/MultilineText.cshtml 的默认 DisplayTemplate,仅包含这一行:

        <span style="white-space: pre-wrap">@this.Model</span>
        

        当然,如果您愿意,您也可以引入一个 css 类,或替换视图中的换行符。
        (我猜这个模板是自动解析的,因为我不需要UIHint 或任何其他参考或注册。)

        使用 DisplayTemplate 而不是引入 HtmlHelper 方法的优势在于,它可以细化到未明确定义的属性和视图(例如,DisplayFor(MyClassWithMultilineProperties) 现在也可以正确显示 MyClassWithMultilineProperties.MultilineText,如果只有属性用[DataType(DataType.MultilineText)]注解。

        【讨论】:

        • 文件名必须是MultilineText.cshtml
        猜你喜欢
        • 2011-03-21
        • 2013-06-26
        • 2013-06-13
        • 1970-01-01
        • 2010-11-26
        • 2012-02-25
        • 2011-09-26
        • 1970-01-01
        • 2015-04-26
        相关资源
        最近更新 更多