What is an MvcHtmlString and when should I use it?

The documentation for MvcHtmlString is not terribly enlightening:

Represents an HTML-encoded string that should not be encoded again.

It's not clear to me what exactly the implications of this are. It seems that some HTML helper methods return an MvcHtmlString, but several examples I've seen online of custom helpers just return a regular string.

Questions:

What is an MvcHtmlString?

When should I choose MvcHtmlString over string and vice versa? Why?


Solution 1:

ASP.NET 4 introduces a new code nugget syntax <%: %>. Essentially, <%: foo %> translates to <%= HttpUtility.HtmlEncode(foo) %>. The team is trying to get developers to use <%: %> instead of <%= %> wherever possible to prevent XSS.

However, this introduces the problem that if a code nugget already encodes its result, the <%: %> syntax will re-encode it. This is solved by the introduction of the IHtmlString interface (new in .NET 4). If the foo() in <%: foo() %> returns an IHtmlString, the <%: %> syntax will not re-encode it.

MVC 2's helpers return MvcHtmlString, which on ASP.NET 4 implements the interface IHtmlString. Therefore when developers use <%: Html.*() %> in ASP.NET 4, the result won't be double-encoded.

Edit:

An immediate benefit of this new syntax is that your views are a little cleaner. For example, you can write <%: ViewData["anything"] %> instead of <%= Html.Encode(ViewData["anything"]) %>.

Solution 2:

This is a late answer but if anyone reading this question is using razor, what you should remember is that razor encodes everything by default, but by using MvcHtmlString in your html helpers you can tell razor that it doesn't need to encode it.

If you want razor to not encode a string use

@Html.Raw("<span>hi</span>")

Decompiling Raw(), shows us that it's wrapping the string in a HtmlString

public IHtmlString Raw(string value) {
    return new HtmlString(value); 
}

"HtmlString only exists in ASP.NET 4.

MvcHtmlString was a compatibility shim added to MVC 2 to support both .NET 3.5 and .NET 4. Now that MVC 3 is .NET 4 only, it's a fairly trivial subclass of HtmlString presumably for MVC 2->3 for source compatibility." source