Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Рассмотрим механизм создания карты сайта. Вряд ли здесь можно предложить какое-то универсальное решение, все зависит непосредственно от веб-приложения, от того, как в нем устроена система маршрутов и ссылок, но в принципе можно в некоторой степени автоматизировать процесс создания файла 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 мы получим сгенерированную карту: