18

I am using MVC3 and am trying to serve content from https, the problem is that when I call Url.Content the files are still served from http using a relative url. I thought this problem was addressed in MVC3 but i can't seem to find any solution. Does anybody know if this issue is inherently solved in MVC3 and how to accomplish it or do I need to create my own helper methods to generate absolute Urls based on protocol?

1
  • The below solutions all work great, but I want to point out that if you are in a load balanced environment then all bets are off as to what URL will be generated. Commented Apr 5, 2012 at 12:17

4 Answers 4

28

You can probably implement your own solution using VirtualPathUtility.ToAbsolute. Probably something like this:

public static class UrlHelperExtension {
  public static string Absolute(this UrlHelper url, string relativeOrAbsolute) {
    var uri = new Uri(relativeOrAbsolute, UriKind.RelativeOrAbsolute);
    if (uri.IsAbsoluteUri) {
      return relativeOrAbsolute;
    }
    // At this point, we know the url is relative.
    return VirtualPathUtility.ToAbsolute(relativeOrAbsolute);
  }
}

which you would use like:

@Url.Absolute(Url.Content("~/Content/Image.png"))

(Didn't test this myself, feel free to play around to make it work right.)

This helps to you to generate absolute URLs for your content files. In order to change the scheme of the resulting URLs, you can create an additional extension method that manipulates the scheme of the given URLs so that they are HTTPS, or something else.

As Khalid points out in the comments, similar extension methods are already available in various open-source projects which you can make use of (given that the license permits). An example one can be found here.

Sign up to request clarification or add additional context in comments.

5 Comments

Your suggestion is very similar to this from Mike Hadlow. google.com/codesearch/p?hl=en#MEucUyOL2vo/trunk/Suteki.Shop/…
I hadn't seen that before, will update the answer to add a link to that. Thanks.
Looks like this would also be worth creating a method for Url.ContentAbsolute or similar instead of needing to wrap them everytime
The Google Code Search link is broken.
I combined your code with this answer: stackoverflow.com/questions/2069922/… to provide full, absolute, urls. Thanks
15

A solution that doesn't use extension methods or hardcode the protocol, as suggested by @BlackTigerX:

Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme)

as suggested in the following article: http://captaincodeman.com/2010/02/03/absolute-urls-using-mvc-without-extension-methods/

1 Comment

This is exactly what I was looking for. My goal was to write my component so that it could be deployed to either http or https environments with no changes, and this let me do it.
10

You can use Url.RouteUrl, some of the overloads take a protocol parameter, looks something like this:

Url.RouteUrl("Product", new { itemId = "123456" }, "https");

Take a look a the overloads and see which one you can use

Comments

1

If you don't want to "build" the url and just want the full path of the current page, this will do the trick

Context.Server.UrlEncode(Context.Request.Url.AbsoluteUri)

I know it's not as elegant as an Extension Method but thought of sharing it for educational purposes

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.