【问题标题】:How can I add non-dynamic nodes to a dynamic node via attributes?如何通过属性将非动态节点添加到动态节点?
【发布时间】:2013-10-09 23:23:55
【问题描述】:

我们想在我们的系统中为所有人添加动态节点。但是我们想使用属性将许多子节点附加到动态节点

例如

[MvcSiteMapNode(Title = "Accidents", ParentKey = "PeopleDetails", Key = "Accidents", PreservedRouteParameters = "personId")]

我们有大约 40 个节点应该是每个人节点的子节点

例如

People > Bob > Absences 
People > Bob > Holidays 
People > Bob > Training

我们希望使用 Action 方法上的属性来配置这些,例如在 Absences Index Action 上添加站点地图属性。 Absences Index 以父节点的 PersonId 作为参数。

我们怎样才能做到这一点?我看到这个article 说如何在 XML 中将非动态子代添加到动态节点。但是我看不到告诉站点地图将基于属性的节点添加到父动态节点的方法。我尝试使用 XML 在站点地图中的每个动态下添加一个中间节点,为其提供 PeoplDetails 的键。然而,它的键似乎已被交换为 Guid(我想使动态节点子节点唯一)

有什么想法吗?我真的不想通过 XML 手动配置 40 多个子节点

【问题讨论】:

    标签: asp.net-mvc mvcsitemapprovider


    【解决方案1】:

    当前无法在使用 MvcSiteMapNodeAttribute 时将“静态”节点添加到动态节点。但是,您可以直接在 IDynamicNodeProvider 实现中添加“静态”节点(即数据驱动节点的子节点)。

    public class PeopleDynamicNodeProvider 
        : DynamicNodeProviderBase 
    { 
        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node) 
        {
            using (var db = new MyContext())
            {
                // Create a node for each album 
                foreach (var person in db.People) 
                { 
                    string personKey = "Person_" + person.Id.ToString();
    
                    DynamicNode dynamicNode = new DynamicNode();
                    dynamicNode.Key = personKey;
                    dynamicNode.Title = person.Name;
                    dynamicNode.ParentKey = "People"; // Attach to a node that is defined somewhere else
                    dynamicNode.RouteValues.Add("id", person.Id.ToString());
    
                    yield return dynamicNode;
    
                    DynamicNode staticNode = new DynamicNode(); 
                    staticNode.Title = person.Name + " Details"; 
                    staticNode.ParentKey = personKey;
                    staticNode.Controller = "People";
                    staticNode.Action = "Details";
                    staticNode.RouteValues.Add("id", person.Id.ToString());
    
                    yield return staticNode;
                }
            }
        } 
    }
    

    如果你真的必须使用 MvcSiteMapNodeAttribute 来定义它们,你可以将上面分成 2 个独立的动态节点提供者,然后在一个属性上声明第二个。

    由于多次调用数据库的额外开销,这会慢很多。您可以通过请求缓存您的人员数据以便在提供者之间共享来解决此问题。

    public class PeopleDynamicNodeProvider 
        : DynamicNodeProviderBase 
    { 
        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node) 
        {
            using (var db = new MyContext())
            {
                // Create a node for each album 
                foreach (var person in db.People) 
                { 
                    string personKey = "Person_" + person.Id.ToString();
    
                    DynamicNode dynamicNode = new DynamicNode();
                    dynamicNode.Key = personKey;
                    dynamicNode.Title = person.Name;
                    dynamicNode.ParentKey = "People"; // Attach to a node that is defined somewhere else
                    dynamicNode.RouteValues.Add("id", person.Id.ToString());
    
                    yield return dynamicNode;
                }
            }
        } 
    }
    
    public class PeopleDetailsDynamicNodeProvider 
        : DynamicNodeProviderBase 
    { 
        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node) 
        {
            using (var db = new MyContext())
            {
                // Create a node for each album 
                foreach (var person in db.People.Where(x => x.PersonCategoryId == node.Key)) 
                { 
                    string personKey = "Person_" + person.Id.ToString();
    
                    DynamicNode staticNode = new DynamicNode(); 
                    staticNode.Title = person.Name + " Details";
                    staticNode.Key = person.PersonCategoryId;
                    staticNode.ParentKey = personKey;
                    staticNode.Controller = "People";
                    staticNode.Action = "Details";
                    staticNode.RouteValues.Add("id", person.Id.ToString());
    
                    yield return staticNode;
                }
            }
        } 
    }
    

    然后您的属性定义将如下所示:

    [MvcSiteMapNode(Title = "Placeholder Title (won't be seen)", Key = "Accidents", PreservedRouteParameters = "personId", DynamicNodeProvider = "MyNamespace.PeopleDetailsDynamicNodeProvider, MyAssembly")]
    

    动态节点提供程序没有限制您生成的节点数必须与数据库中的记录数完全匹配 - 如果需要,您可以根据需要创建更多节点。

    注意:您可能需要根据数据的实际组织方式调整键/父键映射。

    【讨论】:

    • Fantastic 会试一试的。我想也许我们的网站结构相当复杂。人们至少有 40 个子节点,其中大多数都有自己的创建、编辑和添加节点。我们还有许多子节点和 50 个左右的管理实体,每个都可以编辑等资产。什么是太多节点 3000 人 * 40 个子节点 * 4 个子节点对我来说听起来很多?
    • 对于 CRUD 操作,您通常可以使用preservedRouteParameters 来强制您的操作匹配一组固定的节点,因为将这些操作添加到菜单中并不常见(您将首先导航到人员列表页面,然后在该页面上的特定记录上单击“编辑”、“详细信息”或“删除”)。有关一些演示,请参阅这篇文章的代码下载:shiningtreasures.com/post/2013/09/02/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 2013-06-07
    • 1970-01-01
    相关资源
    最近更新 更多