tags:

views:

1523

answers:

2

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?

A: 

You would use an MvcHtmlString if you want to pass raw HTML to an MVC helper method and you don't want the helper method to encode the HTML.

SLaks
Hmm...I thought the whole point of an HTML helper method was to encode HTML. What would I do otherwise with an HTML helper method?
DanM
And, besides that, when would I want to *return* an `MvcHtmlString` from an HTML helper method?
DanM
Pass to or return from. You would want to return one if your HTML helper generates pre-escaped HTML and you don't want anyone else re-escaping it.
SLaks
Okay, I think that gets me a little bit closer, but (at the risk of coming across as a smart ass) how do I decide whether I want anyone else re-escaping it? Is it generally good/bad practice to give someone the ability to mess with escaped html? I've never seen a construct like this before. "It's like a string, but please don't touch it...not that there's anything preventing you from touching it, but we'd prefer you don't." What is that about?
DanM
The point is that unlike a regular string, _this_ string has already been encoded. Therefore, there's no need to touch it.
SLaks
+42  A: 

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"]) %>.

Levi
This is a great answer. Sorry it took me so long to get around to marking it.
DanM
I'd add that MVC 2 is compiled against .Net 3.5, not 4. This means that `MvcHtmlString` doesn't implement `IHtmlString` because that only exists in 4. The `<%:` syntax must _duck-type_ - it will always call `.ToHtmlString()` before `.ToString()` regardless of interface.
Keith
I stand corrected - actually the `MvcHtmlString.Create` method detects whether `IHtmlString` is available and dynamically creates the returned class to support it if it is: http://www.windowsitpro.com/article/net-framework/Encoding-and-Strings/3.aspx
Keith