Генерация sitemap.xml

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 02.01.2017

Рассмотрим механизм создания карты сайта. Вряд ли здесь можно предложить какое-то универсальное решение, все зависит непосредственно от веб-приложения, от того, как в нем устроена система маршрутов и ссылок, но в принципе можно в некоторой степени автоматизировать процесс создания файла sitemap.xml.

Допустим, у нас есть простой контроллер HomeController:

using System.Text;
using System.Web.Mvc;

namespace SitemapGenerator.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Product(int id)
        {
            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        public ActionResult Contact()
        {
            return View();
        }
    }
}

Здесь у нас четыре метода, кроме того, стоит отметить, что метод Product получает элементы из бд по id. Таким образом, в базе данных еще могут храниться множество элементов, для каждого из которых должен формироваться свой путь типа "Home/Product/5".

Теперь добавим в проект новый класс Generator, который будет генерировать файл sitemap.xml:

using SitemapGenerator.Models;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Xml.Linq;

namespace SitemapGenerator
{
    public class Generator
    {
        ProductRepository productRepository;
        public Generator()
        {
            productRepository = new ProductRepository();
        }
        public IReadOnlyCollection<string> GetSitemapNodes(UrlHelper urlHelper)
        {
            List<string> nodes = new List<string>();

            nodes.Add(urlHelper.AbsoluteRouteUrl("Default", new { controller="Home", action="Index"}));
            nodes.Add(urlHelper.AbsoluteRouteUrl("Default", new { controller = "Home", action = "About" }));
            nodes.Add(urlHelper.AbsoluteRouteUrl("Default", new { controller = "Home", action = "Contact" }));

            foreach (int productId in productRepository.GetProductIds())
            {
                nodes.Add(urlHelper.AbsoluteRouteUrl("Default", new { controller = "Home", action = "Product" ,  id = productId }));
            }

            return nodes;
        }

        public string GetSitemapDocument(IEnumerable<string> sitemapNodes)
        {
            XNamespace xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9";
            XElement root = new XElement(xmlns + "urlset");

            foreach (string sitemapNode in sitemapNodes)
            {
                XElement urlElement = new XElement(
                    xmlns + "url",
                    new XElement(xmlns + "loc", Uri.EscapeUriString(sitemapNode)));
                root.Add(urlElement);
            }

            XDocument document = new XDocument(root);
            return document.ToString();
        }
    }
    public static class UrlHelperExtensions
    {
        public static string AbsoluteRouteUrl(this UrlHelper urlHelper,
            string routeName, object routeValues = null)
        {
            string scheme = urlHelper.RequestContext.HttpContext.Request.Url.Scheme;
            return urlHelper.RouteUrl(routeName, routeValues, scheme);
        }
    }
}

Для упрощения создания ссылки по маршруту и его параметрам здесь определен метод расширения AbsoluteRouteUrl, который принимает название маршрута и его параметры.

Метод GetSitemapNodes() класса Generator генерирует все ссылки по методам контроллера. Для получения всех id товаров из базы данных применяется вспомогательный сервис. Для тестирования можно определить следующий класс:

public class ProductRepository
{
    public int[] GetProductIds()
    {
        return new int[] { 1, 2, 3, 4, 5};
    }
}

При варианте, когда все ссылки создаются вручную или программно, но при этом сохраняются в базе данных, задача сильно облегчается, так как в этом случае достаточно получить все эти ссылки из бд.

Метод GetSitemapDocument() создает собственно карту сайта.

Теперь добавим в HomeController метод, который будет отдавать сгенерированную карту сайта:

public ActionResult Sitemap()
{
    Generator sitemapGenerator = new Generator();
    var sitemapNodes = sitemapGenerator.GetSitemapNodes(this.Url);
    string xml = sitemapGenerator.GetSitemapDocument(sitemapNodes);
    return this.Content(xml, "text/xml", Encoding.UTF8);
}

Далее в файле RouteConfig.cs определим дополнительный маршрут для sitemap.xml:

routes.MapRoute(
    name: "sitemap",
    url: "sitemap.xml",
    defaults: new { controller = "Home", action = "Sitemap"}
);
// маршурт по умолчанию
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Кроме того, добавим в файл конфигурации web.config дополнительный узел, который разрешит обработку системой маршрутизации запросов к sitemap.xml:

<system.webServer>
    <handlers>
      <add name="SitemapXml" path="sitemap.xml" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

И теперь при обращении по пути sitemap.xml мы получим сгенерированную карту:

Sitemap.xml в ASP.NET MVC 5
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850