MVC 5 使用操作过滤器定义站点地图节点

MVC 5 Defining Sitemap Nodes with Action Filters

我想用操作过滤器定义站点地图节点,例如:

[SitemapUrl(Frequency = Frequency.Monthly, Priority = 0.9)]
public ActionResult About()
{
    return View();
}

这将生成以下内容:

<url>
  <loc>https://www.example.com/home/about</loc>
  <changefreq>monthly</changefreq>
  <priority>0.9</priority>
</url>

并将其添加到包含所有站点地图节点的集合中,在需要时生成到 sitemap.xml...

我的想法与我们使用 "RouteAttribute" 的行为相同。

我该如何实现?

以下是您可以在 StartUp class:

假设你有一个简单的属性:

public class SitemapUrlAttribute : Attribute
{
    public double Priority {get;set;}
    public  SitemapUrlAttribute(double priority) { Priority = priority; }
}

在启动中class执行以下操作以获取具有此属性的所有操作:

Assembly asm = Assembly.GetExecutingAssembly();
var controllerActionlist = asm.GetTypes()
    .Where(type => typeof(Controller).IsAssignableFrom(type))
    .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly |
                                        BindingFlags.Public))
    .Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute),
        true).Any())
    .Where(m => m.GetCustomAttribute<SitemapUrlAttribute>() != null)
    .Select(
        x =>
            new
            {
                Controller = x.DeclaringType.Name,
                Area = x.DeclaringType.FullName,
                Action = x.Name,
                ReturnType = x.ReturnType.Name,
                Priority = x.GetCustomAttribute<SitemapUrlAttribute>().Priority
            })
    .ToList();

现在您拥有控制器列表,列表中包含您的优先级数据:

这是将数据保存在 xml 文件中的代码:

var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
foreach (var action in controllerActionlist)
{
    var url = urlHelper.Action(action.Action, action.Controller, new {area = action.Area});
    var priority = action.Priority;

    if (something.DoesNotExist(url, priority))
    {
        Add(url, priority);
    }
}

我不知道您将如何保存和检查一个项目(如果它确实存在),因为这将是自定义的,但我认为下一步非常简单。 如果您有任何不清楚的地方,请告诉我!