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 }))" />
Your provided answer:
...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 tohttp://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
andwww.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:...with no issues, as
Request.Url.Scheme
will always be the same due to theHTTP 301
you enforced on the other scheme.