D
D
Dmitry Filandor2015-02-12 15:56:09
Search Engine Optimization
Dmitry Filandor, 2015-02-12 15:56:09

How do you make a dynamic sitemap.xml for a site?

Hello!
There is a site with different categories of type A posts and three more types of posts. Posts are added regularly, I want to make a sitemap.xml, one that is useful for SEO.
I reviewed a lot of articles, but I just can’t understand how to make this sitemap, everywhere there are fragments of examples, or mega-complex options. Does anyone have a working version?
UP1 I
implement the option suggested by @geeek

[NonAction]
        private IEnumerable<SitemapNode> GetSitemapNodes()
        {
            RecordManager recordsManager = new RecordManager();

            // вот так добавляются статические ноды

            //тут будут все узлы
            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 Aphorisms = recordsManager.AforismsForSitemap();   

            foreach (var item in Aphorisms)
            {
                nodes.Add(new SitemapNode(ControllerContext.RequestContext,
                    new { area = "", controller = "Record", action = "AphorismDetail", link = item })
                {
                    Frequency = SitemapFrequency.Weekly,
                    Priority = 0.8
                });
            }

            return nodes;
        }

       


        [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());
            }
        }

//ПОЛУЧИТЬ АФФОРИЗМЫ ДЛЯ Sitemap
        public List<int> AforismsForSitemap()
        {
            if (db == null) { db = new DLL.nissanin_AFFEntities(); }

            var list = (from o in db.Records where o.Type == 1 orderby o.DateGreate descending select o.id_rec).ToList();
            return list;          
        }

As a result, it works, but not quite correctly: aforizmus.com/sitemap.xml
as you can see the link is aforizmus.com/Record/aphorism?item=1428
and it should be: aforizmus.com/aphorism/1431 - I used the sitemap generator, he generated the file for me.
How to lead to aforizmus.com/aphorism/1431 ?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
I
Ilya, 2015-02-12
@LifeAct

Controller:

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");
        }
    }

Model:
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
    }

In Web.config add to system.webServer :
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>

And here are the routes themselves:
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"}
                );

M
mayorovp, 2015-02-12
@mayorovp

https://www.nuget.org/packages/MvcSiteMapProvider/

L
Leonid Sysoletin, 2015-02-12
@sysoletin

For a self-written site, none of the ready-made solutions that work from within the site is suitable. That is, either take some kind of solution that bypasses the site itself and compiles a sitemap based on this, or write a generator yourself, knowing the internal structure of the site.
The first option is bad because some necessary pages may not get into the index, and some unnecessary ones, on the contrary, will get there.
The second version of these shortcomings is devoid of.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question