Расширение MVC Html возвращает строку вместо html-разметки?

#c# #asp.net #asp.net-mvc-3 #razor

#c# #asp.net #asp.net-mvc-3 #razor

Вопрос:

Если у меня есть такое расширение en :

  public static string ImageLink(this HtmlHelper htmlHelper,
                                      string imgSrc, 
                                      string alt, 
                                      string actionName,
                                      string controllerName, 
                                      object routeValues, 
                                      object htmlAttributes, 
                                      object imgHtmlAttributes)
  {

     return @"<img src=""../../Content/images/english.png"" /> ";
  }
  

и я использую его в частичном виде, подобном этому :

 @Html.ImageLink("../../Content/images/english.png","English", "ChangeCulture", "Account", new { lang = "en", returnUrl = this.Request.RawUrl }, null,null)
  

У меня есть вывод, подобный этому :
введите описание изображения здесь

Есть идеи, почему?

Ответ №1:

Причина, по которой это происходит, заключается в том, что @ оператор в Razor автоматически кодирует HTML. Если вы хотите избежать этой кодировки, вам нужно использовать IHtmlString :

 public static IHtmlString ImageLink(
    this HtmlHelper htmlHelper,
    string imgSrc, 
    string alt, 
    string actionName,
    string controllerName, 
    object routeValues, 
    object htmlAttributes, 
    object imgHtmlAttributes
)
{
    return MvcHtmlString.Create(@"<img src=""../../Content/images/english.png"" />");
}
  

что, очевидно, будет гораздо более правильным (и работающим во всех ситуациях, независимо от того, откуда и как вызывается этот помощник), если написано следующим образом:

 public static IHtmlString ImageLink(
    this HtmlHelper htmlHelper,
    string imgSrc,
    string alt,
    string actionName,
    string controllerName,
    object routeValues,
    object htmlAttributes,
    object imgHtmlAttributes
)
{
    var img = new TagBuilder("img");
    var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
    img.Attributes["src"] = urlHelper.Content("~/Content/images/english.png");
    // Don't forget that the alt attribute is required if you want to have valid HTML
    img.Attributes["alt"] = "English flag"; 
    return MvcHtmlString.Create(img.ToString(TagRenderMode.SelfClosing));
}
  

и затем

 @Html.ImageLink("../../Content/images/english.png","English", "ChangeCulture", "Account", new { lang = "en", returnUrl = this.Request.RawUrl }, null,null)
  

будет работать должным образом.

В качестве альтернативы, если вы не можете изменить помощник, вы могли бы использовать @Html.Raw :

 @Html.Raw(Html.ImageLink("../../Content/images/english.png","English", "ChangeCulture", "Account", new { lang = "en", returnUrl = this.Request.RawUrl }, null,null))
  

Ответ №2:

Пусть оно вернет MvcHtmlString вместо этого (мой пример ниже).

  public static MvcHtmlString IconImg(this HtmlHelper htmlHelper, string icon, string title = "", string size = "16x16") {
        string path = VirtualPathUtility.ToAbsolute("~/res/img/icons/"   size   "/"   icon   ".png");
        string imgHtml = "<img src='"   path   "' title='"   title   "' style='border:none' />";
        return new MvcHtmlString(imgHtml);
    }