我正在使用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
的网址,而Url2格式为www.website.org/file.aspx
当我调试我的代码时,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)的代码。问题解决了。
答案 0 :(得分:2)
DisplayFor
帮助器可以利用DisplayTemplates
来获取模型(及其属性)。鉴于您将HTML填充到这些属性中,您只需要直接输出它们。但是,由于MVC会对所有输出进行编码,因此您还需要引入@Html.Raw()
帮助程序。所以,如下所示:
@Html.Raw(Model.Url1)
然而,就模型使用而言,这对MVC来说并不是一个好习惯。我建议(如果必须使用HTML)使用IHtmlString
接口作为您的属性类型(现在它直接使用@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)
答案 1 :(得分:2)
DavidG是对的,你将UI代码放在你的模型中,这不是一件好事。
相反,您应该将URL保留为字符串,并使用UIHintAttribute
告诉MVC您要使用哪个部分来显示数据。
[UIHint("MyCustomHyperlink")]
public string URL1 { get; set; }
[UIHint("MyCustomHyperlink")]
public string URL2 { get; set; }
然后在MyCustomHyperlink.cshtml
/Views/Shared/DisplayTemlpates
的部分
@model string
@if (!string.IsNullOrEmpty(model)) {
<a href="@model" target=\"_blank\">@model</a>
}
else {
<b>no url</b>
}