Show always canonical tag with mvc sitemap provider

845 Views Asked by At

i'm using the MVC Sitemap Provider 4 and want to show always the canonical tag, not only when a second link is existing. Is there somebody who can help me?

1

There are 1 best solutions below

0
On

The best way to do this is to edit (or create another) template to build the canonical tag. If you installed using the NuGet package, in your /Views/Shared/DisplayTemplates folder you will have a CanonicalHelperModel.cshtml file (or with a .ascx extension if you are using webforms instead of razor). The default looks like this:

@model MvcSiteMapProvider.Web.Html.Models.CanonicalHelperModel
@using System.Web.Mvc.Html
@using MvcSiteMapProvider.Web.Html.Models

@if (!String.IsNullOrEmpty(Model.CurrentNode.CanonicalUrl)) {
    <link rel="canonical" href="@Model.CurrentNode.CanonicalUrl" />
}

You can change it so it uses the URL property if no canonical URL was resolved by adding an else block.

@model MvcSiteMapProvider.Web.Html.Models.CanonicalHelperModel
@using System.Web.Mvc.Html
@using MvcSiteMapProvider.Web.Html.Models

@if (!String.IsNullOrEmpty(Model.CurrentNode.CanonicalUrl)) {
    <link rel="canonical" href="@Model.CurrentNode.CanonicalUrl" />
} else {
    <link rel="canonical" href="@string.Format("http://www.mysite.com{0}, Model.CurrentNode.Url)" />
}

You may need to devise a better way to get the base URL (domain name and http/https) and reliably concatenate it with the URL property, as the canonical tag requires an absolute URL. You could just grab the current Request.RawUrl instead of Model.CurrentNode.Url, but you will need to ensure it is properly sanitized (and HTML encoded) before displaying it on the page to prevent XSS attacks. However, if you use the Request.RawUrl just to get the base URL (by loading it into a Uri object and then using the base URL parts), you should be fine.

This will only work for pages that have a matching node defined in the SiteMap. If reading the nodes from an external source such as a database, you should ensure that each record in the database has a node in the SiteMap so there is a one-to-one correlation (at least for the pages you want indexed in search engines). You should not be using preservedRouteParameters in this case. For more information on that subject see How to Make MvcSiteMapProvider Remember a User's Position.

On a side note, there really is no need to do what you are asking because the only pages that require canonical tags are the duplicates.