0

私は2つのコントローラを持って@ Html.MvcSiteMap()SiteMapPathは()例外:。。。私はパン粉トレイルを構築するために<code>@Html.MvcSiteMap().SiteMapPath()</code>を使用している」あいまいなコントローラが見つかり、複数のコントローラタイプ

、一つはのクラスから継承さDealsControllerです。。RegisterRoute機能で

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

をDealsContorllerBase 両クラスは子のインデックス()は、親クラスのインデックスを()よりも優先されます私のMvc.sitemapで 、独自のインデックス()メソッドを持っています210

...

 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.Controllers" プロジェクトの内部で定義された "InvestX.UI.Web" プロジェクトとDealsControllerBase内で定義されたDealsController。

このような全体の例外:

あいまいコントローラ。 'DealsController'に複数のコントローラタイプが見つかりました。マッチタイプは次のとおりです。

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

はControllerBuilder.Currentにあなたのコントローラ 名前空間を追加することにより、検索する場所を狭く考えてみましょう。 DefaultNamespacesまたは は、ControllerTypeResolverFactoryのareaNamespacesToIgnore パラメータに名前空間を追加して除外します。

DealsControllerがDealsControllerBaseから継承されておらず、DealsControllerだけを使用していれば、すべてが問題ありません。 例外は、取るべきIndex()アクション、DealsControllerまたはDealsControllerBaseです。 私の質問は、どのようにmvcSiteMapNodeが親/子コントローラのhierarkyをこのように処理するのですか?

答えて

1

オプション#1

DealsControllerがDealsControllerBaseから継承し、ちょうどDealsControllerを使用していた場合、私が知っている、すべてがうまくなります。

正しい。そして、これはあなたの最善の選択肢であり、それを修正することに関わる時間が過酷でないことを条件としています。 no good reasons for using a base controller in MVCがあります。これは、ASP.NETで行われなければならない方法ですが、MVCの継承はもはやcross-cutting concernsのための最善の選択肢ではありません。必要なものはすべてフレームワークの他の拡張機能(特にglobal filters)で実現できます。

オプション#2

あなたのベースクラスは抽象作る - 彼らは直接MVCにより、コントローラとして使用することができないため、ControllerTypeResolver filters abstract classes out。とにかく、ベースクラスコントローラを直接インスタンス化する必要はありません。

エラーメッセージで指摘したように
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

私はこれをお勧めしませんが、また、あなたのDealsControllerBaseクラス名から単語Controllerを削除することによってこの問題を回避することができます。たとえば、名前をDealsCtrlBaseとします。

+0

こんにちはNightOw888、あなたの迅速な対応と便利なオプションに感謝します。私はオプション#2が私の最高の選択であり、私のために完璧に働いていることが分かった。私は、nodes.titileなどの設定が追加されたDealsControllerクラスにオーバーライドメソッドを追加する必要があります。 – Henry

関連する問題