@ Html.MvcSiteMap()。SiteMapPath()异常:"不明确的控制器。找到多种控制器类型

时间:2016-07-05 05:00:08

标签: c# asp.net-mvc asp.net-mvc-5 mvcsitemapprovider asp.net-mvc-sitemap

我使用@Html.MvcSiteMap().SiteMapPath()构建了breadcrumbs trail。

我有两个控制器,一个是DealsController,它继承自DealsContorllerBase类。 这两个类都有自己的Index()方法,其中child的Index()会覆盖父类的Index()。 在我的Mvc.sitemap中:

<mvcSiteMapNode title="Deals" controller="Deals" action="Index"  >
<mvcSiteMapNode title="Deal" controller="Deals" action="ShowSpecificDeal" />
</mvcSiteMapNode>

在RegisterRoute函数中:

...

        routes.MapRoute(
            "Deals",                                            // Route name
            "Deals",                                            // URL with parameters
            new { controller = "Deals", action = "Index" },     // Parameter defaults
            new[] { "InvestX.UI.Web", "InvestX.UI.Controllers" } // namespaces
        );

...

在内部定义的DealsController&#34; InvestX.UI.Web&#34;在&#34; InvestX.UI.Controllers&#34;内部定义的project和DealsControllerBase;项目

这样的整个例外:

  

不明确的控制器。找到多种控制器类型   &#39; DealsController&#39 ;.匹配的类型是:

     

InvestX.UI.Web.Controllers.DealsController   InvestX.UI.Controllers.DealsControllerBase`1

     

考虑通过添加控制器来缩小要搜索的位置   命名空间到ControllerBuilder.Current.DefaultNamespaces或   通过将名称空间添加到areaNamespacesToIgnore来排除名称空间   ControllerTypeResolverFactory的参数。

我知道如果DealsController不是从DealsControllerBase继承而只是使用DealsController,一切都会好的。 该异常是由采取哪种Index()操作引起的:DealsController或DealsControllerBase。 我的问题是mvcSiteMapNode如何像这样处理父/子控制器hierarky?

1 个答案:

答案 0 :(得分:1)

选项#1

  

我知道DealsController是不是从DealsControllerBase继承而只是使用DealsController,一切都会好的。

正确。这是你最好的选择,只要修复它所涉及的时间并不令人望而却步。有no good reasons for using a base controller in MVC。这是在ASP.NET中必须完成的事情,但MVC继承不再是cross-cutting concerns的最佳选择。您可以使用框架的其他扩展来完成所需的一切(尤其是global filters)。

选项#2

使您的基类抽象 - ControllerTypeResolver filters abstract classes out,因为它们不能被MVC直接用作控制器。无论如何,您的基类控制器都不太可能直接实例化。

public abstract class DealsControllerBase : Controller
{
    ...
}

选项#3

正如错误消息中所指出的,将基本控制器命名空间添加到AreaNamespacesToIgnore

内部DI

<add key="MvcSiteMapProvider_ControllerTypeResolverAreaNamespacesToIgnore" value="InvestX.UI.Controllers"/>

外部DI

显示的Ninject示例 - 其他DI容器类似。

this.Kernel.Bind<IControllerTypeResolverFactory>().To<ControllerTypeResolverFactory>()
            .WithConstructorArgument("areaNamespacesToIgnore", new string[] { "InvestX.UI.Controllers" });

选项#4

正如错误消息中所指出的,您还可以将所有控制器名称空间显式添加到ControllerBuilder.Current.DefaultNamespaces

ControllerBuilder.Current.DefaultNamespaces.Clear();
ControllerBuilder.Current.DefaultNamespaces.Add("InvestX.UI.Web.Controllers");
ControllerBuilder.Current.DefaultNamespaces.Add("SomeOtherNamespace.Controllers");

请注意,只有当您注册路线中的任何名称空间时,此功能才有效。

选项#5

我不建议这样做,但您也可以通过从Controller班级名称中删除DealsControllerBase一词来避免此问题。例如,将其命名为DealsCtrlBase