我使用@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?
答案 0 :(得分:1)
我知道DealsController是不是从DealsControllerBase继承而只是使用DealsController,一切都会好的。
正确。这是你最好的选择,只要修复它所涉及的时间并不令人望而却步。有no good reasons for using a base controller in MVC。这是在ASP.NET中必须完成的事情,但MVC继承不再是cross-cutting concerns的最佳选择。您可以使用框架的其他扩展来完成所需的一切(尤其是global filters)。
使您的基类抽象 - ControllerTypeResolver
filters abstract classes out,因为它们不能被MVC直接用作控制器。无论如何,您的基类控制器都不太可能直接实例化。
public abstract class DealsControllerBase : Controller
{
...
}
正如错误消息中所指出的,将基本控制器命名空间添加到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" });
正如错误消息中所指出的,您还可以将所有控制器名称空间显式添加到ControllerBuilder.Current.DefaultNamespaces
。
ControllerBuilder.Current.DefaultNamespaces.Clear();
ControllerBuilder.Current.DefaultNamespaces.Add("InvestX.UI.Web.Controllers");
ControllerBuilder.Current.DefaultNamespaces.Add("SomeOtherNamespace.Controllers");
请注意,只有当您不注册路线中的任何名称空间时,此功能才有效。
我不建议这样做,但您也可以通过从Controller
班级名称中删除DealsControllerBase
一词来避免此问题。例如,将其命名为DealsCtrlBase
。