Контроллер:
public class SeoController : Controller
{
private const string SitemapsNamespace = "http://www.sitemaps.org/schemas/sitemap/0.9";
[NonAction]
private IEnumerable<SitemapNode> GetSitemapNodes()
{
// вот так добавляются статические ноды
var nodes = new List<SitemapNode>
{
new SitemapNode(ControllerContext.RequestContext,
new {area = "", controller = "Home", action = "Index"})
{
Frequency = SitemapFrequency.Monthly,
Priority = 0.5
},
new SitemapNode(ControllerContext.RequestContext,
new {area = "", controller = "Home", action = "About"})
{
Frequency = SitemapFrequency.Monthly,
Priority = 0.5
}
};
// а вот так динамические
var items = model.Collection.ToList();
foreach (var item in items)
{
nodes.Add(new SitemapNode(ControllerContext.RequestContext,
new {area = "", controller = "Home", action = "blablabla", link = item.Id})
{
Frequency = SitemapFrequency.Weekly,
Priority = 0.8
});
}
}
[NonAction]
private string GetSitemapXml()
{
XNamespace xmlns = SitemapsNamespace;
var nodes = GetSitemapNodes();
var root = new XElement(xmlns + "urlset");
foreach (var node in nodes)
{
root.Add(
new XElement(xmlns + "url",
new XElement(xmlns + "loc", Uri.EscapeUriString(node.Url)),
node.Priority == null
? null
: new XElement(xmlns + "priority",
node.Priority.Value.ToString("F1", CultureInfo.InvariantCulture)),
node.LastModified == null
? null
: new XElement(xmlns + "lastmod",
node.LastModified.Value.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:sszzz")),
node.Frequency == null
? null
: new XElement(xmlns + "changefreq", node.Frequency.Value.ToString().ToLowerInvariant())
));
}
using (var ms = new MemoryStream())
{
using (var writer = new StreamWriter(ms, Encoding.UTF8))
{
root.Save(writer);
}
return Encoding.UTF8.GetString(ms.ToArray());
}
}
[OutputCache(Duration = 60*60, Location = System.Web.UI.OutputCacheLocation.Any)]
public ActionResult SitemapXml()
{
var content = GetSitemapXml();
return Content(content, "application/xml", Encoding.UTF8);
}
[OutputCache(Duration = 60*60, Location = System.Web.UI.OutputCacheLocation.Any)]
public FileContentResult RobotsText()
{
var content = new StringBuilder("User-agent: *" + Environment.NewLine);
content.Append("Host: ").Append("www.твой-домен.ru" + Environment.NewLine);
content.Append("Sitemap: ")
.Append("www.твой-домен.ru")
.Append("/sitemap.xml" + Environment.NewLine);
return File(
Encoding.UTF8.GetBytes(content.ToString()),
"text/plain");
}
}
Модель:
public class SitemapNode
{
public string Url { get; set; }
public DateTime? LastModified { get; set; }
public SitemapFrequency? Frequency { get; set; }
public double? Priority { get; set; }
public SitemapNode(string url)
{
Url = url;
Priority = null;
Frequency = null;
LastModified = null;
}
public SitemapNode(RequestContext request, object routeValues)
{
Url = GetUrl(request, new RouteValueDictionary(routeValues));
Priority = null;
Frequency = null;
LastModified = null;
}
private string GetUrl(RequestContext request, RouteValueDictionary values)
{
var routes = RouteTable.Routes;
var data = routes.GetVirtualPathForArea(request, values);
if (data == null)
{
return null;
}
var baseUrl = request.HttpContext.Request.Url;
var relativeUrl = data.VirtualPath;
return request.HttpContext != null &&
(request.HttpContext.Request != null && baseUrl != null)
? new Uri(baseUrl, relativeUrl).AbsoluteUri
: null;
}
}
public enum SitemapFrequency
{
Never,
Yearly,
Monthly,
Weekly,
Daily,
Hourly,
Always
}
В Web.config добавь в system.webServer :
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
Ну и сами маршруты:
routes.MapRoute(
name: "sitemap.xml",
url: "sitemap.xml",
defaults: new {controller = "Seo", action = "SitemapXml"}
);
routes.MapRoute(
name: "robots.txt",
url: "robots.txt",
defaults: new {controller = "Seo", action = "RobotsText"}
);