12


6

MVC 2エリア登録ルートの順序

MVC 2 Preview 2では、AreaRegistrationが各エリアのルートを任意の順序でロードしていることに気付きました。 一方を他方に優先させる良い方法はありますか?

たとえば、「サイト」と「管理者」の2つの領域があります。 どちらも "Blog"コントローラを持っています。

私は以下のことを望みます:

/admin/ --> go to Admin's Blog controller
/       --> go to Site's Blog controller.

問題はそれが最初にサイトのルートをロードしているということです、それで私が次に行くときそれは admin / {controller} / {action} / {id}`の代わりに `{controller} / {action} / {id} URL "/ admin /" "Site"エリアにAdminコントローラがないので、私はそれから404を得ます。

どちらの領域もデフォルトで "Blog"コントローラになっています。 私は単純に `site / {controller} / …​`をURLにすることができることを理解していますが、可能であればルートに置く方がよいでしょう。 また、グローバルなRegisterRoutes関数でデフォルトルートを維持しようとしましたが、その場合は "Sites"エリアに送信されません。

前もって感謝します!

4 Answer


30


Haackedが言ったことは別として、それはエリア登録(そしてその結果それらのルート)を注文することは非常に可能です。 あなたがしなければならないのはあなたが望むどんな順番でも手動で各領域を登録することです。 RegisterAllAreas()を呼び出すほど洗練されていませんが、確実に実行可能です。

protected void Application_Start(){var area1reg = new Area1AreaRegistration();} var area1context = new AreaRegistrationContext(area1reg.AreaName、RouteTable.Routes); area1reg.RegisterArea(area1context);

var area2reg = new Area2AreaRegistration(); var area2context = new AreaRegistrationContext(area2reg.AreaName、RouteTable.Routes); area2reg.RegisterArea(area2context);

var area3reg = new Area3AreaRegistration(); var area3context = new AreaRegistrationContext(area3reg.AreaName、RouteTable.Routes); area3reg.RegisterArea(area3context); }

もう1つの選択肢は、RegisterAllAreas()のコードを取得し、それを独自のアプリにコピーして、順序を決定するための独自のメカニズムを構築することです。 ビルトインメソッドが持っているすべての派手なキャッシングロジックが欲しいなら、それはコピーするべきかなりのコードですが、あなたのアプリはそれさえ必要としないかもしれません。


7


現在、地域を注文することはできません。 ただし、順序を問わないように、各領域をできる限り他の領域から独立させようとすることは理にかなっていると思います。

たとえば、デフォルトの\ {controller} / \ {action} / \ {id}のルートではなく、各コントローラーの特定のルートに置き換えます。 またはそのデフォルトルートに制約を追加します。

注文を許可するオプションについては検討中ですが、機能を複雑にしすぎないようにします。


4


私はこの解決策を作ります:

AreaUtils.cs

システムを使用する。 System.Web.Mvcを使用します。 System.Web.Routingを使用します。

名前空間SledgeHammer.Mvc.Site {public static class Utils {public static void RegisterArea(RouteCollectionルート、オブジェクト状態)ここで、T:AreaRegistration

{AreaRegistration registration =(AreaRegistration)Activator.CreateInstance(typeof(T));

AreaRegistrationContext context = new AreaRegistrationContext(registration.AreaName、routes、state);

string tNamespace = registration.GetType()。ネームスペース。 if(tNamespace!= null){context.Namespaces.Add(tNamespace "。*"); }

registration.RegisterArea(context); }}

}

global.asaxの場合:

Utils.RegisterArea(RouteTable.Routes、null); Utils.RegisterArea(RouteTable.Routes、null);

//AreaRegistration.RegisterAllAreas(); do not dublicate register areas

生成されたエリア登録コードに必要な変更はありません。 また、要求内のドメインの種類(システムドメインまたはユーザーサイト)でルートをフィルター処理するために、ルートにカスタム定数を使用します。

これは私の地域登録の例です。

名前空間SledgeHammer.MVC.Site.Areas.System {パブリッククラスSystemAreaRegistration:AreaRegistration {パブリックオーバーライド文字列AreaName {get {return "System"; }}

パブリックオーバーライドvoid RegisterArea(AreaRegistrationContext context){context.MapRoute( "System_Feedback"、 "Feedback"、新しい{controller = "Feedback"、action = "Index"}); context.MapRoute( "システム情報"、 "情報/ {アクション} / {ID}"、新規{コントローラ= "情報"、アクション= "インデックス"、ID = UrlParameter.Optional}); }}}


名前空間SledgeHammer.MVC.Site.Areas.ClientSites {パブリッククラスClientSitesAreaRegistration:AreaRegistration {パブリックオーバーライド文字列AreaName {get {return "ClientSites"; }}

public override void RegisterArea(AreaRegistrationContext context){context.MapRoute( "ClientSites_default"、 "{controller} / {action} / {id}"、new {controller = "Site"、アクション= "Index"、id = UrlParameter.Optional new {Host = new SiteInGroups( "clients")}); }}}


4


参考のため、

MVC3(MVC2を知らない)では、単にルートを特定のエリア/コントローラにマッピングしたいときは、単にグローバルルートを使うことができます。 名前空間/領域を指定することを忘れないでください。

routes.MapRoute( "CatchRoot"、 ""、new {controller = "SITEBLOG-CONTROLLER-NAME"、アクション= "Index"}).DataTokens.Add( "area"、 "SITE-AREA-NAME");