0

我正在使用@Html.MvcSiteMap().SiteMapPath()构建面包屑路径。

我有两个控制器,一个是从 DealsContorllerBase 类继承的 DealsController。这两个类都有自己的 Index() 方法,其中子类的 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
        );

...

在“InvestX.UI.Web”项目中定义的 DealsController 和在“InvestX.UI.Controllers”项目中定义的 DealsControllerBase。

整个例外是这样的:

模棱两可的控制器。为“DealsController”找到了多种控制器类型。匹配的类型是:

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

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

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

4

1 回答 1

1

选项1

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

正确的。这是您最好的选择,前提是修复它所涉及的时间并不令人望而却步。在MVC 中使用基本控制器没有充分的理由。这是在 ASP.NET 中必须完成的事情的方式,但是使用 MVC 继承不再是横切关注点的最佳选择。您可以使用框架的其他扩展(尤其是全局过滤器)来完成您需要的一切。

选项#2

使您的基类抽象 -ControllerTypeResolver过滤器将类抽象出来,因为它们不能被 MVC 直接用作控制器。无论如何,您的基类控制器不太可能需要直接实例化。

public abstract class DealsControllerBase : Controller
{
    ...
}

选项#3

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

内部DI

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

外部直接投资

显示的 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

于 2016-07-05T10:31:47.400 回答