Ensure "www" always contained in links generated by MVC built-in helpers for canonicity

244 views Asked by At

Using C# MVC .NET 4.5 with my RouteConfig.cs set to append trailing slashes and convert URLs to lower case:

routes.AppendTrailingSlash = true;
routes.LowercaseUrls = true;

I have the following canonical link tag in the HTML of my views:

<link rel="canonical" href="@Url.Action("Index", Html.GetTitleType(Model.TitleType), new { i = Model.Title.Title_Id }, Request.Url.Scheme)" />

This works great but needs some modification. My preferred canonical URL structure is "http://www.example.com/something/1234/" - If I'm however browsing the site at "http://example.com" then the canonical link rendered is "http://example.com/something/1234/" which totally defeats the purpose. How can I ensure the canonical tag contains "http://www" no matter what? I could obviously hardcode the URL structure myself, but would prefer a more elegant solution.

Update: the best I could come up with is this:

<link rel="canonical" href="@string.Format("{0}{1}", "http://www.example.com", @Url.Action("Index", Html.GetTitleType(Model.TitleType), new { i = Model.Title.Title_Id }))" />

"http://www.example.com" could also be stored as a key-value pair in web.config so that the final result looks like this:

<link rel="canonical" href="@string.Format("{0}{1}", @System.Web.Configuration.WebConfigurationManager.AppSettings["canonical_root_URL"], @Url.Action("Index", Html.GetTitleType(Model.TitleType), new { i = Model.Title.Title_Id }))" />
2

There are 2 answers

0
trashr0x On BEST ANSWER

Your provided answer:

<link rel="canonical" href="@string.Format("{0}{1}", @System.Web.Configuration.WebConfigurationManager.AppSettings["canonical_root_URL"], @Url.Action("Index", Html.GetTitleType(Model.TitleType), new { i = Model.Title.Title_Id }))" />

...will work fine as it will match scenarios such as http://example.com/something/1234, www.example.com/something/1234, http://example.com/something/1234?randomVar=5 and so on to http://www.example.com/something/1234/.

However, this is a good example of solving a problem that creates other problems. Patrick Hofman's and Jeow Li Huan's comments are correct — you have your canonicity issue figured out but now you have to deal with example.com and www.example.com generating their own set of cookies etc. As such, pick one scheme and stick to it by doing a permanent URL redirection (HTTP 301) on URLs matching the other scheme. You will then be able to use your original code:

<link rel="canonical" href="@Url.Action("Index", Html.GetTitleType(Model.TitleType), new { i = Model.Title.Title_Id }, Request.Url.Scheme)" />

...with no issues, as Request.Url.Scheme will always be the same due to the HTTP 301 you enforced on the other scheme.

0
AnotherGeek On

Select your site in IIS manager then click on binding, add a binding with the host name example.com (without www).