我正在处理 MVC 3 中的通用详细信息页面,它在 View 中看起来像这样:
<fieldset>
<legend style="font-size:large">Info</legend>
<div class="display-label">Url1:</div>
<div class="display-field">
@Html.DisplayFor(model => model.Url1)
</div>
<div class="display-label">Url2:</div>
<div class="display-field">
@Html.DisplayFor(model => model.Url2)
</div>
<fieldset>
在模型中像这样:
public HtmlString Url1
{
get
{
if (!string.IsNullOrEmpty(Url1))
{
return new HtmlString("<a href=\"" + Url1
+ "\" target=\"_blank\">" + Url1 + "</a>");
}
return new HtmlString("<b>no url</b>");
}
}
public HtmlString Url2
{
get
{
if (!string.IsNullOrEmpty(Url2))
{
return new HtmlString("<a href=\"" + Url2
+ "\" target=\"_blank\">" + Url2 + "</a>");
}
return new HtmlString("<b>no url</b>");
}
}
Url1 是 http://www.website.com
形式的 url,Url2 是 www.website.org/file.aspx 形式的 url
当我调试我的代码时,Url1 的 HtmlString 正确显示,但 Url2 的 HtmlString 却没有。生成的 Html 源代码如下所示:
<div class="display-label">Url1</div>
<div class="display-field">
<a href="http://www.website.org">website</a> <br/>
</div>
<div class="display-label">Url2</div>
<div class="display-field">
</div>
以前有没有人遇到过这样的问题,如果有,您是如何解决的?
更新
更新代码以使用 @Model.Url1 而不是 @Html.DisplayFor(Url1)。问题解决了。
最佳答案
DisplayFor
助手可以利用模型(及其属性)的 DisplayTemplates
。鉴于您正在将 HTML 填充到这些属性中,您只想直接输出它们。但是,由于 MVC 对所有输出进行编码,因此您还需要引入 @Html.Raw()
帮助器。所以,类似于以下内容:
@Html.Raw(Model.Url1)
但是,就模型使用而言,这对于 MVC 来说确实不是好的做法。我建议(如果你必须使用 HTML)为你的属性类型使用 IHtmlString
接口(interface)(所以现在它直接使用 @Model.Url1
输出)或制作一个自定义对象和显示模板(UIHintAttribute
的绝佳用例)。
IHtmlString 示例:
class UrlViewModel : IHtmlString {
private readonly String url;
private UrlViewModel(String url) {
this.url = url;
}
public String ToHtmlString(){
if (String.IsNullOrEmpty(this.url)){
return new HtmlString("<a ...>...</a>");
}
return new HtmlString("<b>...</b>");
}
}
然后你的模型变成:
class MyViewModel {
private String url1;
private String url2;
public MyViewModel(String url1, String url2){
this.ur1l = url1;
this.url2 = url2;
}
public UrlViewModel Url1 { get; set; }
public UrlViewModel Url2 { get; set; }
}
最后是您的观点:
@Html.Url1 @* MVC automatically recognized an IHtmlString *@
@Html.Url2 @* implementation and outputs without escaping *@
UIHint 用法
您的模型得到装饰(但保留类型):
class MyViewModel {
[UIHint("MyUrl")]
public String Url1 { get; set; }
[UIHint("MyUrl")]
public String Url2 { get; set; }
}
此外,只需向模型提供 URL(而不是 HTML)。然后,添加一个新的 DisplayTemplate (~/Views/Shared/DisplayTemplates/MyUrl.cshtml):
@model String
@if (!String.IsNullOrEmpoty(Model)) {
<a href="@Model" target="_blank">@Model</a>
} else{
<b>No Url</b>
}
而且你可以继续使用@Html.DisplayFor(x => x.Url1)
关于c# - MVC 3 Html.DisplayFor(...) 代码不生成 HTML 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26805935/