DamianEdwards / RazorSlices

Lightweight Razor-based templates for ASP.NET Core without MVC, Razor Pages, or Blazor.
MIT License
297 stars 12 forks source link

Issue when rendering URL with embedded "&" codes #40

Closed jtsom closed 1 month ago

jtsom commented 2 months ago

When rendering a cshtml page, that has a URL with encoded & values (&) (image tag src attribute, for example), the rendered URL has the URL incorrectly encoded:

<img src="@Model.ImageUrl" />

where ImageUrl is something like:

https://example.com/images/image.png?v1=test&amp;v2=test2&amp;v3=test3

The rendered URL is:

https://example.com/images/image.png?v1=test&amp;amp;v2=test2&amp;amp;v3=test3

Also the quotes in the above img tag are missing:

<img src=https://example.com/images/image.png?v1=test&amp;amp;v2=test2&amp;amp;v3=test3 />

This was found when trying to pull images from Azure Storage, where the validation key needs to be appended to the url. Needless to say, this causes Azure to not render the image, returning an error;

I had to manually fix and remove the extra "amp;" from the rendered HTML.

DamianEdwards commented 2 months ago

This is by design as far as I can tell. ASP.NET Core Razor Pages or MVC with Razor Views does the same thing. If you want to disable encoding already encoded values you can wrap the value in HtmlString, e.g. <img src="(new HtmlString(@Model.ImageUrl))" />.

jtsom commented 2 months ago

I'm not sure it's "by design". This code was adapted from existing ASP.NET MVC code that renders a partial, which is then converted to a PDF - it does not have this issue of incorrectly rendering the embedded & .

Also, as mentioned, it strips out the quotes in the rendered img tag. If I add spaces, the quotes will appear, but with the additional spaces:

<img src=" @Model.ImageUrl " />
<img src=" https://example.com/images/image.png?v1=test&amp;amp;v2=test2&amp;amp;v3=test3 " />

FWIW - I tried using the HtmlString method mentioned, but the renderer still incorrectly encodes the &

DamianEdwards commented 2 months ago

Can you create and share a project that reproduces the issue as I'm not able to see the behavior you're describing.

jtsom commented 1 month ago

Sorry it took long to get this set up.

Load this project up and run it. (I don't know why the Swagger UI gives an error - not sure what's going on there).

Put a breakpoint on line 40

image

Load up the /GetTest endpoint and step over the break point, and look at the rendered code to see the problem. The & is being incorrectly "encoded".

Thanks. net8test.zip

Update: I figured out the Swagger issue - I have "app.Map( )" in the code - it should be "app.MapGet ( )"

DamianEdwards commented 1 month ago

Yes this is expected because the text value is already HTML encoded. Razor Pages/Views does the exact same thing. I added a Razor Page to your app and rendered the img tag the same way and get the same result: image

If you want write pre-encoded HTML (i.e. raw HTML) you need to render an HtmlString instance instead, e.g. @(new HtmlString(Model.Url))

jtsom commented 1 month ago

Thanks, I guess. We have a .Net MVC web app, that renders a similar string into HTML and that conversion doesn't happen.

I also did try using the HtmlString method and it did the same thing.

Oh well, I have a workaround that fixes the HTML, so will just keep using that.

DamianEdwards commented 1 month ago

If you can share a repro of an MVC app not HTML encoding a string returned from a Razor expression I'll gladly take another look. My guess is it's passing it through Html.Raw(), e.g. @Html.Raw(Model.Url)