Как я могу добавить нединамические узлы в динамический узел через атрибуты?
Мы хотим добавить динамические узлы для всех людей в нашей системе. Однако мы хотим присоединить множество дочерних узлов к динамическому узлу, используя атрибуты.
например
[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")]
В провайдере динамического узла нет ограничений на то, что количество создаваемых вами узлов должно точно соответствовать количеству записей в базе данных - вы можете создать больше узлов, если вам нужно, в зависимости от ваших требований.
Примечание. Возможно, вам придется настроить отображение ключа / родительского ключа в зависимости от того, как на самом деле организованы ваши данные.