A minimalist library for creating sitemap files inside ASP.NET MVC and ASP.NET Core MVC applications
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src/SimpleMvcSitemap Deprecated Mobile property Sep 19, 2017
test Trying a different path for targets file Jun 14, 2017
.gitattributes Added gittattributes Dec 30, 2013
.gitignore Removed vs config file Aug 21, 2015
LICENSE Added license file Dec 13, 2013
README.md Updated the description Jun 11, 2018
SimpleMvcSitemap.sln Moved MvcWebsite Jun 13, 2017
appveyor.yml Revert "Trying detailed build" Jun 13, 2017

README.md

SimpleMvcSitemap

A minimalist library for creating sitemap files inside ASP.NET MVC/ASP.NET Core MVC applications.

SimpleMvcSitemap lets you create sitemap files inside action methods without any configuration. It also supports generating sitemap index files. Since you are using regular action methods you can take advantage of caching and routing available in the framework.

Table of contents

Installation

Install the NuGet package on your MVC project.

Install-Package SimpleMvcSitemap

.NET Framework

SimpleMvcSitemap references the ASP.NET MVC assembly in the earliest package. Since it's a strongly-named assembly, you will have to keep assembly binding redirection in Web.config if you are working with ASP.NET MVC 4/5. These sections are created for you in project templates.

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
      <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Examples

You can use SitemapProvider class to create sitemap files inside any action method. You don't even have to provide absolute URLs, SimpleMvcSitemap can generate them from relative URLs. Here's an example:

public class SitemapController : Controller
{
    public ActionResult Index()
    {
        List<SitemapNode> nodes = new List<SitemapNode>
        {
            new SitemapNode(Url.Action("Index","Home")),
            new SitemapNode(Url.Action("About","Home")),
            //other nodes
        };

        return new SitemapProvider().CreateSitemap(new SitemapModel(nodes));
    }
}

SitemapNode class also lets you specify the optional attributes:

new SitemapNode(Url.Action("Index", "Home"))
{
    ChangeFrequency = ChangeFrequency.Weekly,
    LastModificationDate = DateTime.UtcNow,
    Priority = 0.8M
}

Sitemap Index Files

Sitemap files must have no more than 50,000 URLs and must be no larger then 10MB as stated in the protocol. If you think your sitemap file can exceed these limits you should create a sitemap index file. If you have a logical seperation, you can create an index manually.

List<SitemapIndexNode> sitemapIndexNodes = new List<SitemapIndexNode>
{
   new SitemapIndexNode(Url.Action("Categories","Sitemap")),
   new SitemapIndexNode(Url.Action("Products","Sitemap"))
};

return new SitemapProvider().CreateSitemapIndex(new SitemapIndexModel(sitemapIndexNodes));

If you are dealing with dynamic data and you are retrieving the data using a LINQ provider, SimpleMvcSitemap can handle the paging for you. A regular sitemap will be created if you don't have more nodes than the sitemap size.

Generating sitemap index files

This requires a little configuration:

public class ProductSitemapIndexConfiguration : SitemapIndexConfiguration<Product>
{
    private readonly IUrlHelper urlHelper;

    public ProductSitemapIndexConfiguration(IQueryable<Product> dataSource, int? currentPage, IUrlHelper urlHelper)
        : base(dataSource,currentPage)
    {
        this.urlHelper = urlHelper;
    }

    public override SitemapIndexNode CreateSitemapIndexNode(int currentPage)
    {
        return new SitemapIndexNode(urlHelper.RouteUrl("ProductSitemap", new { currentPage }));
    }

    public override SitemapNode CreateNode(Product source)
    {
        return new SitemapNode(urlHelper.RouteUrl("Product", new { id = source.Id }));
    }
}

Then you can create the sitemap file or the index file within a single action method.

public ActionResult Products(int? currentPage)
{
    var dataSource = products.Where(item => item.Status == ProductStatus.Active);
    var productSitemapIndexConfiguration = new ProductSitemapIndexConfiguration(dataSource, currentPage, Url);
    return new DynamicSitemapIndexProvider().CreateSitemapIndex(new SitemapProvider(), productSitemapIndexConfiguration);
}

Google Sitemap Extensions

You can use Google's sitemap extensions to provide detailed information about specific content types like images, videos, mobile, news or alternate language pages. You can still use relative URLs for any of the additional URLs.

Images

using SimpleMvcSitemap.Images;

new SitemapNode(Url.Action("Display", "Product"))
{
    Images = new List<SitemapImage>
    {
        new SitemapImage(Url.Action("Image","Product", new {id = 1})),
        new SitemapImage(Url.Action("Image","Product", new {id = 2}))
    }
}

Videos

using SimpleMvcSitemap.Videos;

new SitemapNode("http://www.example.com/videos/some_video_landing_page.html")
{
    Video = new SitemapVideo(title: "Grilling steaks for summer",
                             description: "Alkis shows you how to get perfectly done steaks every time",
                             thumbnailUrl: "http://www.example.com/thumbs/123.jpg", 
                             contentUrl: "http://www.example.com/video123.flv")
}

News

using SimpleMvcSitemap.News;

new SitemapNode("http://www.example.org/business/article55.html")
{
    News = new SitemapNews(newsPublication: new NewsPublication(name: "The Example Times", language: "en"),
                           publicationDate: new DateTime(2014, 11, 5, 0, 0, 0, DateTimeKind.Utc),
                           title: "Companies A, B in Merger Talks")
}

Mobile (Probably deprecated by Google)

using SimpleMvcSitemap.Mobile;

new SitemapNode("http://mobile.example.com/article100.html")
{
    Mobile = new SitemapMobile()
};

Alternate language pages

using SimpleMvcSitemap.Translations;

new SitemapNode("abc")
{
    Translations = new List<SitemapPageTranslation>
    {
        new SitemapPageTranslation("http://www.example.com/deutsch/", "de"),
		new SitemapPageTranslation("http://www.example.com/english/", "en")
    }
}

XSL Style Sheets

SimpleMvcSitemap supports XSL style sheets by version 3. Keep in mind that XML stylesheets are subjected to the same origin checks.

using SimpleMvcSitemap.StyleSheets;

new SitemapModel(new List<SitemapNode> { new SitemapNode("abc") })
{
    StyleSheets = new List<XmlStyleSheet>
    {
        new XmlStyleSheet("/sitemap.xsl")
    }
};

You can see how you can utilize multiple XSL style sheets in this tutorial.

Custom Base URL

SimpleMvcSitemap can generate absolute URLs from the relative URLs using the HTTP request context. If you want to customize this behaviour, you can implement IBaseUrlProvider interface and pass it to the SitemapProvider class.

public class BaseUrlProvider : IBaseUrlProvider
{
    public Uri BaseUrl => new Uri("http://example.com");
}

var sitemapProvider = new SitemapProvider(new BaseUrlProvider());

Unit Testing and Dependency Injection

SitemapProvider class implements the ISitemapProvider interface which can be injected to your controllers and be replaced with test doubles. All methods are thread safe so they can be used with singleton life cycle.

public class SitemapController : Controller
{
    private readonly ISitemapProvider _sitemapProvider;

    public SitemapController(ISitemapProvider sitemapProvider)
    {
        _sitemapProvider = sitemapProvider;
    }
	
    //action methods
}

License

SimpleMvcSitemap is licensed under MIT License. Refer to license file for more information.