Как я могу добавить нединамические узлы в динамический узел через атрибуты?

Мы хотим добавить динамические узлы для всех людей в нашей системе. Однако мы хотим присоединить множество дочерних узлов к динамическому узлу, используя атрибуты.

например

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

У нас есть около 40 узлов, которые должны быть дочерними для каждого узла человека

Например

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

Мы хотели бы настроить их, используя атрибуты в методе действия, например, добавить атрибут карты сайта для действия индекса отсутствия. Индекс отсутствий принимает PersonId родительских узлов в качестве своих параметров.

Как мы можем достичь этого? Я вижу, что в этой статье рассказывается, как сделать это в XML Добавление нединамических дочерних элементов в динамические узлы. Однако я не вижу способа сообщить карте сайта о добавлении узлов на основе атрибутов в родительский динамический узел. Я попытался добавить промежуточный узел под каждую динамику в sitemap, используя XML, предоставив ему ключ PeoplDetails. Однако его ключ, похоже, заменен на Guid (я думаю, чтобы сделать динамические узлы потомками уникальными)

Есть идеи? Я действительно не хочу вручную настраивать более 40 дочерних узлов через XML

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")]

В провайдере динамического узла нет ограничений на то, что количество создаваемых вами узлов должно точно соответствовать количеству записей в базе данных - вы можете создать больше узлов, если вам нужно, в зависимости от ваших требований.

Примечание. Возможно, вам придется настроить отображение ключа / родительского ключа в зависимости от того, как на самом деле организованы ваши данные.

Другие вопросы по тегам