Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Html.Raw insists on encoding quotes

MVC4 razor view. Given that a string backgroundImage is set like this:

backgroundImage = string.Format("background: url('{0}') top left no-repeat;", project.MainImage);

Why does this

<div class="spotlight slide teaser-text" id="@slideId" style="@Html.Raw(backgroundImage)">

produce

<div class="spotlight slide teaser-text" id="spotlight-0" style="background: url(&#39;/media/215/spotlight01.jpg&#39;) top left no-repeat;">

Html.Raw, new MvcHtmlString and MvcHtmlString.Create all behave similarly.

I would expect it to produce

<div class="spotlight slide teaser-text" id="spotlight-0" style="background: url('/media/215/spotlight01.jpg') top left no-repeat;">

(note the quotes).

like image 817
AndyC Avatar asked Jul 11 '13 15:07

AndyC


1 Answers

I have had a look at the compiled DLL for a razor template containing this markup. As far as I can see, the issue is this.

Html.Raw turns a string into an HtmlString. HttpUtility.HtmlEncode treats IHtmlString instances differently to normal strings, in that it doesn't apply Html encoding.

When the programmatically defined string is given in the context of the attribute, a call is made to

this.WriteAttribute(...)

with data appropriate to generate the attribute. Part of this data is the HtmlString generated by the call to Html.Raw. Another part is a flag indicating that the value is not a literal.

Because of the not-literal flag status, the WriteAttribute method eventually calls HtmlEncode. But it calls this not on the HtmlString, but on the string value of this object. So you do end up with an HTML encoded value in the output.

Outside the context of an attribute, the call is made to

this.Write(...)

and this doesn't suffer from the same problem. So it seems like a bug to me (at least if I've accurately traced it all through).

like image 71
Yellowfog Avatar answered Oct 12 '22 03:10

Yellowfog