3

I made my html helper method

public static string MedalImage(this HtmlHelper helper, Color color)
    {
        var builder = new TagBuilder("img");
        switch (color)
        {
            case Color.Blue:
                builder.MergeAttribute("src", "/Content/Medals/blueMedal.png");
                break;
            default:
                builder.MergeAttribute("src", "/Content/Medals/redMedal.png");
                break;
        }
        builder.MergeAttribute("alt", "Image not found");
        return builder.ToString(TagRenderMode.SelfClosing);
    }

But when I want to use it in View like this @Html.MedalImage(HtmlHelpers.Color.Red) then it renders:

<img alt="Image not found" src="/Content/Medals/redMedal.png" />

And in this case it does not make image, only text.

But when I use @Html.Raw(Html.MedalImage(HtmlHelpers.Color.Red)) it does work as expected and renders my image. Can someone tell me why? Or how to fix my helper so I don't have to use Html.Raw method?

MacakM
  • 1,804
  • 3
  • 23
  • 46

1 Answers1

4

The standard behaviour of MVC Razor is to HTML-encode every string. The only time it will not do so is if the object is an IHtmlString, which is little more than a wrapper interface for strings.

By wrapping your string as an IHtmlString, Razor will treat it as 'already encoded' and 'ready to be sent as-is'. There are at least two ways to do this:

var htmlStr1 = new HtmlString(myStringThatContainsHtml);
var htmlStr2 = new MvcHtmlString(myStringThatContainsHtml);

or applied to your code:

return new HtmlString(builder.ToString(TagRenderMode.SelfClosing));
return new MvcHtmlString(builder.ToString(TagRenderMode.SelfClosing));

And then your method signature needs to be changed:

public static IHtmlString MedalImage(...) { ... }

The reason that there are two ways is historic. MVC2 did not have the IHtmlString interface, and it had only the MvcHtmlString class. From MVC3 the IHtmlString interface was created and also the class HtmlString, and MvcHtmlString now inherits from HtmlString. For more on that, see HtmlString vs. MvcHtmlString.

Community
  • 1
  • 1
Peter B
  • 22,460
  • 5
  • 32
  • 69