c# - MVC 3 Html.DisplayFor(...) 代码不生成 HTML 代码

标签 c# html asp.net-mvc asp.net-mvc-3

我正在处理 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/

相关文章:

javascript - 如果用户使用手机,隐藏某些元素,提供按钮使元素重新出现

html - 将元素保持在 div 的底部,同时保持它在流中

c# - 我应该通过 RedirectToAction 还是 TempData 传递值?

javascript - 进行 ajax 调用时如何尊重客户端验证

C# 我如何进行加密?

c# - 我应该为每个 Web 请求使用静态缓存的 ResourceManager 还是新实例?有关系吗?

c# - WP7如何让网格尺寸适配图像尺寸

c# - System.ExecutionEngineException 仅在调试时出现

javascript - 将 div 保持在对话框中的固定位置

asp.net-mvc - MVC : Binding datetime value (bootstrap datetime picker) from view to model