muonlab » 2011 » November

random .NET and web development musings

I wanted a simple way to manage canonical links in ASP.NET MVC.

It would have been nice to work these out automatically from the route tables, but for the project I am working on, its far too convoluted to be done easily, I’d rather maintain a fixed definition for each action.

Step up a custom `ActionFilterAttribute`:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class CanonicalUrl : ActionFilterAttribute
	readonly string url;

	public CanonicalUrl(string url)
		this.url = url;

	public override void OnResultExecuting(ResultExecutingContext filterContext)
		var uri = filterContext.RequestContext.HttpContext.Request.Url;
		var fullyQualifiedUrl = (uri.Scheme + "://" + uri.Host + this.url).ToLowerInvariant();

		foreach (var key in filterContext.RouteData.Values.Keys)
			fullyQualifiedUrl = fullyQualifiedUrl.Replace("{" + key.ToLowerInvariant() + "}",

		filterContext.Controller.ViewData["CanonicalUrl"] = fullyQualifiedUrl;
		filterContext.HttpContext.Response.Headers.Add("link", "<" + fullyQualifiedUrl + ">; rel=\"canonical\"");


You can then decorate your actions like this:

public ActionResult Show(string name)

Make sure you stick the link element in your page’s head:

<% if(ViewData["CanonicalUrl"] != null){ %>
	<link rel="canonical" href="<%: ViewData["CanonicalUrl"] %>" />
<%} %>