我刚刚使用当前的MvcSiteMapProvider MVC5(来自nuget,从MVC4升级)获得了“问题”。 我曾经在创建它们时为DynamicNodes的RouteValues添加一个routevalue“title” 在我的DynamicNodeProvider中。 这在以前的版本中运行良好,但是在尝试此操作时没有出现错误:
An exception of type 'MvcSiteMapProvider.Collections.Specialized.ReservedKeyException' occurred in MvcSiteMapProvider.dll but was not handled in user code
Additional information: The node with key 'someKey' may not add a route value with the key 'title' and value 'someValue' to the RouteValues dictionary because the key is a reserved name. Reserved names are keys that are meant for use internally by MvcSiteMapProvider rather than a dictionary value.
我收到消息,我不应该将“title”添加为自定义路由参数。 但是,我的完整项目在路径定义中使用“{title}”,我将不得不将所有内容从标题更改为“{id}”(或其他内容)。
现在我的问题:是否可以以某种方式将自定义“标题”路由值添加到动态节点?或者这根本不可能?
提前致谢!
答案 0 :(得分:0)
您可以通过继承ReservedAttributeNameProvider并覆盖IsRouteAttribute方法来解决此限制。
public class MyReservedAttributeNameProvider
: ReservedAttributeNameProvider
{
public MyReservedAttributeNameProvider(
IEnumerable<string> attributesToIgnore
) : base(attributesToIgnore)
{
}
public override bool IsRouteAttribute(string attributeName)
{
return attributeName != "visibility"
&& !attributesToIgnore.Contains(attributeName)
&& !attributeName.StartsWith("data-");
}
}
然后,您可以使用外部DI注入新的ReservedAttributeNameProvider(通过升级到其中一个DI包)。例如,您只需要用自己的注册替换现有注册。实现这是在StructureMap中看起来的样子,但您可以轻松地使用任何其他DI容器。
this.For<IReservedAttributeNameProvider>().Use<MyReservedAttributeNameProvider>()
.Ctor<IEnumerable<string>>("attributesToIgnore").Is(new string[0]);
我建议您长期在GitHub上打开new issue。我无法想到为什么必须全面实施 - 这种属性名称的限制应该仅在以XML格式配置节点时才存在,并且在这种情况下应该没有错误消息 - 只是默默地忽略该值。此外,MvcSiteMapNodeAttribute具有相同缺陷的事实是从v3延续的糟糕设计决策。应该有一个RouteValues“字典”(好吧,JSON字典)来定义那里的值,而不是把所有东西塞进属性,并试图猜测哪些值去哪里。但无论哪种方式,从MvcSiteMapNodeAttribute,动态节点或自定义ISiteMapNodeProvider实现中排除任何属性名称都没有意义,因为属性不再更新属性,反之亦然。