Search code examples
asp.netasp.net-mvcrazorrelative-path

Resolving an image uri relative to application root


I am using Asp.Net MVC 5. Assume for this question that my application is being served from localhost:9000/app.

I've got this in my _layout.cshtml:

<img src="@Url.Content("~/Content/logo.png")" />

When the user requests localhost:9000/app/foobar, the image URI is correctly resolved to localhost:9000/app/Content/logo.png.

But when the user requests localhost:9000/app/folder/bender_is_great, the image URI resolves to localhost:9000/app/folder/Content/logo.png.

How do I get the image URI to always resolve relative to the application root, not relative to the requested path?

Edit: Server.MapPath("~/Content/logo.png") has the same issue. It's resolving relative to the requested path, not the application root.


Solution

  • Turns out it was my URL rewrite rules for friendly HTML5 URLs without the hashbang (#!). The rewriting engine set an item on the application: "IIS_WasUrlRewritten". Url.Content(...) calls into UrlUtil, which pays attention to this item and changes its behavior. This Microsoft Support page says:

    To resolve the tilde notation to the rewritten URLs by using the same behavior as in Web Pages Razor V2, set the IIS_WasUrlRewritten context to false in each Web page or in Application_BeginRequest in Global.asax for the global setting as follows:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        Context.Items["IIS_WasUrlRewritten"] = false;
    }
    

    Note The change of the IIS_WasUrlRewritten context affects the tilde notation not only in the HTML elements, but also in the MVC helper methods. For example, if it is set to false, the tilde notation in Url.Content and Html.ActionLink returns the rewritten URLs.

    So far this code hasn't caused any problems in my application and has resolved the issue.