DotnetSitemapGenerator 1.0.1
See the version list below for details.
dotnet add package DotnetSitemapGenerator --version 1.0.1
NuGet\Install-Package DotnetSitemapGenerator -Version 1.0.1
<PackageReference Include="DotnetSitemapGenerator" Version="1.0.1" />
paket add DotnetSitemapGenerator --version 1.0.1
#r "nuget: DotnetSitemapGenerator, 1.0.1"
// Install DotnetSitemapGenerator as a Cake Addin #addin nuget:?package=DotnetSitemapGenerator&version=1.0.1 // Install DotnetSitemapGenerator as a Cake Tool #tool nuget:?package=DotnetSitemapGenerator&version=1.0.1
DotnetSitemapGenerator
A minimalist library for creating sitemap files inside ASP.NET Core applications and generating sitemap.xml files.
DotnetSitemapGenerator 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.
Advantages of DotnetSitemapGenerator
This builds upon SimpleMvcSitemap by uhaciogullari by allowing the generator to save to a physical .xml file directly with additional testing. Also this project is being actively developed and used in production applications, and upgraded to use updated dotnet features and language versions.
Table of contents
- Installation
- Examples
- Serializing Sitemap to a File
- Sitemap Index Files
- DateTime Format
- Google Sitemap Extensions
- XSL Style Sheets
- Custom Base URL
- Unit Testing and Dependency Injection
- License
<a id="installation">Installation</a>
Install the NuGet package on your MVC project.
<a id="examples">Examples</a>
You can use SitemapProvider class to create sitemap files inside any action method. You don't even have to provide absolute URLs, DotnetSitemapGenerator 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.ToLocalTime(),
Priority = 0.8M
}
<a id="serializing-to-a-file">Serializing Sitemap to a File</a>
To serialize a sitemap directly to a file this is done slightly differently than using the controller as you use the XMLSerializer directly.
IXmlSerializer sitemapProvider = new XmlSerializer(); // Instantiate a new serializer
// Add all your mappings to this list
List<SitemapNode> nodes = new() {
new($"https://yoursite.com/homepage")
{
LastModificationDate = newDateTime.ToLocalTime(),
ChangeFrequency = ChangeFrequency.Daily,
Priority = 1.0M
}
};
// second parameter xmlSavePath is the path to where you want to save your file, often "sitemap.xml"
// third parameter (true in this case) is used to mark whether the outputed xml file should be
// formatted in a way that it is easily readable by human eyes which is helpful with visual validation
sitemapProvider.Serialize(new SitemapModel(nodes), xmlSavePath, true);
<a id="sitemap-index-files">Sitemap Index Files</a>
Sitemap files must have no more than 50,000 URLs and must be no larger then 50MB 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, DotnetSitemapGenerator can handle the paging for you. A regular sitemap will be created if you don't have more nodes than the sitemap size.
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);
}
<a id="datetime-format">DateTime Format</a>
You should convert your DateTime values to local time. Universal time format generated by .NET is not accepted by Google. You can use .ToLocalTime() method to do the conversion.
<a id="google-sitemap-extensions">Google Sitemap Extensions</a>
You can use Google's sitemap extensions to provide detailed information about specific content types like images, videos, news or alternate language pages. You can still use relative URLs for any of the additional URLs.
<a id="images">Images</a>
using DotnetSitemapGenerator.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}))
}
}
<a id="videos">Videos</a>
By version 4, multiple videos are supported. Start using Videos property if you are upgrading from v3 to v4.
using DotnetSitemapGenerator.Videos;
new SitemapNode("http://www.example.com/videos/some_video_landing_page.html")
{
Videos = new List<SitemapVideo>
{
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")
}
}
<a id="news">News</a>
using DotnetSitemapGenerator.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")
}
<a id="translations">Alternate language pages</a>
using DotnetSitemapGenerator.Translations;
new SitemapNode("abc")
{
Translations = new List<SitemapPageTranslation>
{
new SitemapPageTranslation("http://www.example.com/deutsch/", "de"),
new SitemapPageTranslation("http://www.example.com/english/", "en")
}
}
<a id="style-sheets">XSL Style Sheets</a>
DotnetSitemapGenerator supports XSL style sheets by version 3. Keep in mind that XML stylesheets are subjected to the same origin checks.
using DotnetSitemapGenerator.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.
<a id="base-url">Custom Base URL</a>
DotnetSitemapGenerator 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());
<a id="di">Unit Testing and Dependency Injection</a>
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
}
<a id="license">License</a>
DotnetSitemapGenerator is licensed under MIT License. Refer to license file for more information.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp1.0 was computed. netcoreapp1.1 was computed. netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard1.6 is compatible. netstandard2.0 was computed. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen30 was computed. tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 1.6
- Microsoft.AspNetCore.Mvc (>= 1.0.3)
- NETStandard.Library (>= 1.6.1)
- System.Linq.Queryable (>= 4.0.1)
- System.Xml.XmlSerializer (>= 4.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.