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

时间:2017-09-15 19:19:47

标签: asp.net-mvc sitemap asp.net-mvc-5

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

[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”的行为相同。

我该如何实现?

1 个答案:

答案 0 :(得分:1)

您可以在StartUp课程中执行以下操作:

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

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

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

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

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