DynamicNodeProviderBase + Pagination

时间:2015-09-27 17:50:45

标签: asp.net-mvc mvcsitemapprovider

我有ASP.NET MVC项目,我有一些模块。有些模块有分页。为了测试和理解 MvcSiteMapProvider 我使用一个模块论坛并创建 ForumDynamicNodeProvider类

public class ForumDynamicNodeProvider : DynamicNodeProviderBase
{
    private readonly IForumsService _forumsService;

    public ForumDynamicNodeProvider(IForumsService forumsService)
    {
        this._forumsService = forumsService;
    }

    public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
    {
        string rootTitle = ManagerLocalization.Get("Forums", "FORUMS");


        var nodes = new List<DynamicNode>
                        {
                            new DynamicNode
                                {
                                    Title = rootTitle,
                                    Controller = "Forums",
                                    Action = "Index",
                                    Key = "forum_home"
                                }
                        };

        var forums = this._forumsService.GetForums<ForumNode>().ToList();
        var topics = this._forumsService.GetTopics<TopicNode>().ToList();

        foreach (var forum in forums)
        {
            var parentForum = this.GetParentForum(forums, forum);
            string parentKey = parentForum?.Id.ToString() ?? "home";

            var forumRouteValue = new Dictionary<string, object> { { "forumName", forum.NameTranslit } };

            nodes.Add(new DynamicNode
            {
                Key = $"forum_{forum.Id}",
                ParentKey = $"forum_{parentKey}",
                Title = forum.Name,
                Controller = "Forums",
                Action = "ShowForum",
                RouteValues = forumRouteValue
            });
        }

        foreach (var topic in topics)
        {
            var forum = forums.FirstOrDefault(item => item.Id == topic.ForumId);
            var forumRouteValue = new Dictionary<string, object> { { "forum", forum.NameTranslit },  { "topicName", topic.TitleTranslite }, {"page", 0 } };

            nodes.Add(new DynamicNode
            {
                Key = $"topic_{topic.Id}",
                ParentKey = $"forum_{topic.ForumId}",
                Title = topic.Title,
                Controller = "Forums",
                Action = "ShowTopic",
                RouteValues = forumRouteValue
            });
        }

        return nodes;
    }

    private ForumNode GetParentForum(List<ForumNode> forums, ForumNode forum)
    {
        if (forum.ForumId > 0)
        {
            return forums.FirstOrDefault(item => item.Id == forum.ForumId);
        }

        return null;
    }
}

但我无法为分页找到一个好的决定。为了方便起见,我可以使用页面前缀作为密钥并制作重复的DynamicNode。但这不是一个好主意,因为当我有1000个主题示例,每个主题有20个页面时,我必须创建20000个DynamicNode。也许有其他决定?

1 个答案:

答案 0 :(得分:1)

对于环境上下文(例如页码),您可以对指定键的任何值使用PreservedRouteParametersforce a match。这些键匹配请求中的路由值或查询字符串参数(如果路由值相同则优先使用。)

foreach (var forum in forums)
{
    var parentForum = this.GetParentForum(forums, forum);
    string parentKey = parentForum?.Id.ToString() ?? "home";

    var forumRouteValue = new Dictionary<string, object> { { "forumName", forum.NameTranslit } };

    // Always match the "page" route value regardless of its value
    var forumPreservedRouteParameters = new List<string>() { "page" };

    nodes.Add(new DynamicNode
    {
        Key = $"forum_{forum.Id}",
        ParentKey = $"forum_{parentKey}",
        Title = forum.Name,
        Controller = "Forums",
        Action = "ShowForum",
        RouteValues = forumRouteValue,
        PreservedRouteParameters = forumPreservedRouteParameters
    });
}
  

注意:当您使用PreservedRouteParameters时,它们会包含在当前请求生成的URL中(如果提供),如果请求中未提供,则不包含在URL中。因此,如果您在同一个祖先中有多个页码,则需要为每个页码指定一个单独的路由键名称,否则当前页码将从当前请求传递到祖先节点。