MvcSiteMapProvider MVC5 - 添加"标题"路线值不起作用(预期)

时间:2014-07-30 13:42:23

标签: asp.net-mvc mvcsitemapprovider

我刚刚使用当前的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}”(或其他内容)。

现在我的问题:是否可以以某种方式将自定义“标题”路由值添加到动态节点?或者这根本不可能?

提前致谢!

1 个答案:

答案 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实现中排除任何属性名称都没有意义,因为属性不再更新属性,反之亦然。