【发布时间】:2012-02-20 07:01:39
【问题描述】:
令人尴尬的新手问题:
我的模型中有一个 string 字段,其中包含换行符。
@Html.DisplayFor(x => x.MultiLineText)
不显示换行符。
显然我可以在模型中做一些摆弄,并创建另一个字段,用<br/> 替换\n,但这看起来很笨拙。完成这项工作的教科书方法是什么?
【问题讨论】:
标签: asp.net-mvc-3 razor
令人尴尬的新手问题:
我的模型中有一个 string 字段,其中包含换行符。
@Html.DisplayFor(x => x.MultiLineText)
不显示换行符。
显然我可以在模型中做一些摆弄,并创建另一个字段,用<br/> 替换\n,但这看起来很笨拙。完成这项工作的教科书方法是什么?
【问题讨论】:
标签: asp.net-mvc-3 razor
尝试使用@Html.Raw("<p>" + Html.LabelFor(x => x.Name) + "</p>")
【讨论】:
您为您的数据创建一个显示模板。 这是一篇详细说明如何操作的帖子。 How do I create a MVC Razor template for DisplayFor()
在该模板中,您可以将换行符实际翻译成
以及任何其他需要进行演示的工作。
【讨论】:
在您看来,您可以尝试类似的方法
@Html.Raw(Html.Encode(Model.MultiLineText).Replace("\n", "<br />"))
【讨论】:
.Replace("\r\n", ...)。此外,在我看来,下面的solution from cwills 要好得多。
ViewData而不是常规属性,但是在ASP.NET Core Razor中,我不得不使用@Html.Raw(((string)ViewData["MyText"]).Replace("\n", "<br />"))
@Html.Raw(field.Replace("\n", "<br />"))
显示模板可能是最好的解决方案,但如果你知道你只是显示一个字符串,还有另一个简单的选择是使用 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)
【讨论】:
一个 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)
【讨论】:
MvcHtmlString.Empty,而是调用标准的 HtmlHelper.DisplayFor 方法,以便可以使用任何 NullDisplayText 装饰。
DisplayTemplate 而不是引入HtmlHelper 方法的优势在于,它可以细化到未明确定义的属性和视图(请参阅my answer)。
我建议使用 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 <span class="multiline">@Model</span> 创建一个 DisplayTemplate
这是另一个扩展方法选项。
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);
}
【讨论】:
灵感来自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