0

@Html.MvcSiteMap().SiteMapPath()ブレッドクラムトレイルを構築するために使用しています。

私は2つのコントローラーを持っています.1つは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」プロジェクト内で定義された DealController と、「InvestX.UI.Controllers」プロジェクト内で定義された DealsControllerBase。

この例外全体:

あいまいなコントローラー。「DealsController」のコントローラー タイプが複数見つかりました。一致したタイプは次のとおりです。

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

コントローラーの名前空間を ControllerBuilder.Current.DefaultNamespaces に追加して検索する場所を絞り込むか、ControllerTypeResolverFactory の areaNamespacesToIgnore パラメーターに追加して名前空間を除外することを検討してください。

DealsController が DealsControllerBase から継承されておらず、DealsController を使用するだけであれば、すべて問題ありません。この例外は、DealsController または DealsControllerBase のどちらの Index() アクションを実行するかによって発生しました。私の質問は、 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"/>

外部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ます。

于 2016-07-05T10:31:47.400 に答える