Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Html.Raw escaping ampersand in anchor tag in ASP.NET MVC 4?

Tags:

I have a URL I would like to render in an anchor tag as-is in a Razor view. I would have thought Html.Raw would be the way to go:

@{
    string test = "http://someurl.com/someimage.png?a=1234&b=5678";
}

<div>
    <a href="@Html.Raw(test)">Test</a>
</div>

But this doesn't work. The ampersand gets encoded and the HTML is rendered as:

<div>
    <a href="http://someurl.com/someimage.png?a=1234&amp;b=5678">Test</a>
</div>

The strange thing is that if I do the Html.Raw call outside of the anchor tag, the HTML output is as expected:

<div>
    @Html.Raw(test)
<div>

is rendered as:

<div>
    http://someurl.com/someimage.png?a=1234&b=5678
</div>

Can anyone explain why this is?

Edit:

Tried a few other things out, and found that the following works as expected:

<div data-url="@Html.Raw(test)"></div>

outputs:

<div data-url="http://someurl.com/someimage.png?a=1234&b=5678"></div>

To add a little more context, my goal is not actually to use the URL in an anchor tag, since hrefs can be HTML encoded and still work (I just used the anchor tag case as an example). Rather I wish to use the URL in an <object> <param> value tag for a Flash object. The Flash object doesn't properly recognize the HTML encoded URL, but I can't get the raw URL to output correctly.

I am at a loss. Time to break out the MVC source code I guess...

like image 381
Joe Waller Avatar asked Aug 15 '12 02:08

Joe Waller


People also ask

Why we use Html raw in MVC?

I use the Html. Raw to print a raw html content, for example when I send some thing like ViewBag. div = "<div> Hello </div>"; from the controller to the view side it does not print a raw html content unless I use the Html.

Why not use Html raw?

Raw can result in a XSS vulnerability being exploitable since an attacker can craft a special URL containing a malicious JavaScript payload that will be executed by the victim's browser if he or she sends an invalid 2FA confirmation code.

What is an anchor in asp net?

The Anchor Tag Helper generates a route directly to that controller action using the URL /Speaker/Evaluations. The generated HTML: HTML Copy. <a href="/Speaker/Evaluations">Speaker Evaluations</a> If asp-controller or asp-action is specified in addition to asp-route , the route generated may not be what you expect.


2 Answers

This is happening because something in the pipeline (I'd guess razor but I'd need to look it up) attribute encodes all attribute values. This should not affect the browser from reaching your desired location however.

You can test this with the @Html.ActionLink(text, action, routeAttributes) overload.

@Html.ActionLink("Test", "Index", new { tony = "1", raul = 2 })

outputs

<a href="/?tony=1&amp;raul=2">Test</a>

In regards to your edit, you just need to make the entire <param> part of your raw value.

@{
    var test = "<param src=\"http://someurl.com/someimage.png?a=1234&b=5678\">";
}

<div>
    <object>
    @Html.Raw(test)
    </object>
</div>
like image 110
Nick Larsen Avatar answered Oct 20 '22 11:10

Nick Larsen


Like this:

@{
    string test = "http://someurl.com/someimage.png?a=1234&b=5678";
}

<div>
    <a href="@Html.Raw(Html.AttributeEncode(test))">Test</a>
</div>

produces valid markup:

<div>
    <a href="http://someurl.com/someimage.png?a=1234&amp;b=5678">Test</a>
</div>

But this doesn't work. The ampersand gets encoded and the HTML is rendered as:

But that's exactly how a valid markup should look like. The ampersand must be encoded when used as an attribute. Don't worry, the browser will perfectly fine understand this url.

Notice that the following is invalid markup, so you don't want this:

<div>
    <a href="http://someurl.com/someimage.png?a=1234&b=5678">Test</a>
</div>
like image 39
Darin Dimitrov Avatar answered Oct 20 '22 11:10

Darin Dimitrov