Dynamic sitemap in ASP.NET MVC

前端 未结 7 624
小蘑菇
小蘑菇 2021-01-30 09:04

I\'m trying to create an automatic sitemap ActionResult that outputs a valid sitemap.xml file. The actual generation of the file is not a problem, but I can\'t seem to figure o

相关标签:
7条回答
  • 2021-01-30 10:05

    Define an ActionFilterAttribute like this to put on any Action method that is an actual page that you want to list in your sitemap:-

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class MVCUrlAttribute : ActionFilterAttribute
    {
        public string Url { get; private set; }
    
        public MVCUrlAttribute(string url)
        {
            this.Url = url;
        }
    
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            // Put this 'canonical url' into the model (which feeds the view)
            // to help search engines with issues of duplicate content
            filterContext.Controller.ViewData["CanonicalUrl"] = url;
            base.OnResultExecuting(filterContext);
        }
    }
    

    Now add something like this to your Global application start code, or use it in your sitemap.xml generating code:-

       // Find all the MVC Routes
        Log.Debug("*** FINDING ALL MVC ROUTES MARKED FOR INCLUSION IN SITEMAP");
        var allControllers = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(Controller)));
        Log.DebugFormat("Found {0} controllers", allControllers.Count());
    
        foreach (var controllerType in allControllers)
        {
            var allPublicMethodsOnController = controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
            Log.DebugFormat("Found {0} public methods on {1}", allPublicMethodsOnController.Count(), controllerType.Name);
    
            foreach (var publicMethod in allPublicMethodsOnController)
            {
                var mvcurlattr = publicMethod.GetCustomAttributes(true).OfType<MVCUrlAttribute>().FirstOrDefault();
                if (mvcurlattr != null)
                {
                    string url = mvcurlattr.Url;
                    Log.Debug("Found " + controllerType.Name + "." + publicMethod.Name + " <-- " + url);
                    Global.SiteMapUrls.Add(url);  //<-- your code here using url
                }
            }
        }
    

    You can extend the attribute class to perhaps also include the frequency of update hint.

    0 讨论(0)
提交回复
热议问题