Captain Codeman Captain Codeman

Absolute URLs using MVC (without extension methods)

Contents

Introduction

Do you need to generate absolute URLs within your MVC application?

Often this will be in the form of URLs used outside of the web-browser such as those used within Atom Publishing Protocol collections or maybe links that are going to be sent out in emails. Basically, anything where the regular relative URL won’t do.

A quick search of Google will turn up a number of blog posts or forum answers showing how to do this by creating extension methods for the Url helper class but really, everything that is needed is already baked into the MVC framework already … and I’ve only just realized it after using it since the CTP releases!

All you need to do is specify the protocol within the Url.Action or Url.RouteUrl method. Here are some regular looking URLs:

<%= Url.Action(<span class="str">"About"</span>, <span class="str">"Home"</span>) %><br />
<%= Url.RouteUrl(<span class="str">"Default"</span>, <span class="kwrd">new</span> { Action = <span class="str">"About"</span> }) %><br />

Which produce the same output:

/Home/About

/Home/About

If we add the protocol then it changes to:

<%= Url.Action(<span class="str">"About"</span>, <span class="str">"Home"</span>, <span class="kwrd">null</span>, <span class="str">"http"</span>) %><br />
<%= Url.RouteUrl(<span class="str">"Default"</span>, <span class="kwrd">new</span> { Action = <span class="str">"About"</span> }, <span class="str">"http"</span>) %><br />

http://localhost:51868/Home/About

http://localhost:51868/Home/About

Instead of having the ‘http’ hard-coded like that you can instead use whatever protocol was used for the request so URLs will be correct whether they are using http or https (assuming they don’t need to be a specific one), e.g.:

<%= Url.Action(<span class="str">"About"</span>, <span class="str">"Home"</span>, <span class="kwrd">null</span>, Request.Url.Scheme) %><br />
<%= Url.RouteUrl(<span class="str">"Default"</span>, <span class="kwrd">new</span> { Action = <span class="str">"About"</span> }, Request.Url.Scheme) %><br />

If you just pass the protocol / scheme then the host name and port number are generated automatically based on the site that the app is running on. You can also pass the host name as well if you want (if the public host name doesn’t match the one the site is actually running on).

This works for the Url helper only, the protocol isn’t an option in the Html helper used to general complete html anchor links but I’m guessing that if you need an absolute URL you are needing something else beyond a plain link anyway and it isn’t too much trouble to just define the anchor element in a view and use the Url helper in the href attribute only.