2008-09-04 12 views
3

次のようなシナリオのルーティングやサンプルを探しています:MVCルーティングのコントローラのカテゴリ? (別のネームスペースに重複しているコントローラ名)

一般的な例は{controller}/{action}/{idあなたが持っていると思いストアの製品検索を行うためのシナリオでそう}

public class ProductsController: Controller 
{ 
    public ActionResult Search(string id) // id being the search string 
    { ... } 
} 

は、あなたがこれを行うには、いくつかの店舗を持っていたし、あなたが一貫し、その後にどのような方法があることを望んでいたと言います{カテゴリ}/{コントローラ}/{操作}/{ID}

特定の店舗を特定して検索することはできますが、別の店舗には異なる検索方法を使用することができますか?

(あなたは、URL内の関数自体よりも高い優先度であることを店の名前を必要とした場合)または、それが降りてくるでしょう

:それは偉大な例ではないかもしれない

public class ProductsController: Controller 
{ 
    public ActionResult Search(int category, string id) // id being the search string 
    { 
     if(category == 1) return Category1Search(); 
     if(category == 2) return Category2Search(); 
     ... 
    } 
} 

、基本的には、同じコントローラ名を使用し、いくつかの異なるシナリオで単純なURLを使用することですか、または一意のコントローラ名を必要としていて、わずかに異なる名前空間/ディレクトリに入れることができませんか?

編集追加する:私はカテゴリがあり、URLをしたい、と特定のコントローラが唯一の特定のカテゴリの下で動作することを可能性があるため

を私はこれをしたい他の理由があります。

IE:

/本/検索/アイテム/検索+用語< - その/検索/アイテム/検索+用語</

に動作します - 動作しません - 検索コントローラ理由許可されていません。

+0

1.0リリースの「エリア」の概念はこれに対処していますか? – hometoast

答えて

1

妥協なしにこれを行う最良の方法は、IControllerFactoryを継承して独自のControllerFactoryを実装することです。実装するCreateControllerメソッドは、RouteHandlerとControllerActionInvokerによる要求を処理するコントローラインスタンスを作成するハンドルを処理します。コンベンションではコントローラを作成するときにコントローラの名前を使用するため、この機能をオーバーライドする必要があります。同じ名前の複数のコントローラが異なるフォルダにあるので、ルートに基づいてコントローラを作成するためのカスタムロジックを配置します。その後、あなたのルートと同じように、アプリケーションの起動時にカスタムコントローラファクトリを登録する必要があります。

コントローラを作成するときに考慮する必要がある別の領域は、ビューを見つけることです。すべてのビューで同じビューを使用する予定の場合は、使用される規約と異なるものを実行する必要はありません。ビューの整理も計画している場合は、独自のViewLocatorを作成し、コントローラファクトリで作成するときにコントローラに割り当てる必要があります。

コードのアイデアを得るには、私はこの質問に関連しているので、コントローラ名が同じであるため、この質問に関連するいくつかの質問があります。私は参照のためのリンクを含んだ。

別のルートが、いくつかの妥協が新しいAcceptVerbs属性を使用することで必要な場合があります。詳細はquestionをチェックしてください。私はまだこの新しい機能を使っていませんが、別のルートかもしれません。

4

実際には検索でさえ見つからず、this questionのASP .NETフォーラムをスキャンしました。あなたは長い間、あなたがしている名前空間属するルートの資格として、名前空間の任意の部分の下に同じ名前のコントローラを持つことができ、これを使用して

(あなたが必要であれば、あなたはルートごとに複数の名前空間を持つことができます!)

しかし、ここからコントローラの下にディレクトリを置くことができます。もしコントローラが "MyWebShop.Controllers"なら、 "Shop1"のディレクトリを置くでしょう、そして名前空間は "MyWebShop.Controllers.Shop1"になります

これが動作します:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     var shop1namespace = new RouteValueDictionary(); 
     shop1namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop1" 
     })); 

     routes.Add("Shop1", new Route("Shop1/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop1namespace 
     }); 

     var shop2namespace = new RouteValueDictionary(); 
     shop2namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop2" 
     })); 

     routes.Add("Shop2", new Route("Shop2/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop2namespace 
     }); 

     var defaultnamespace = new RouteValueDictionary(); 
     defaultnamespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers" 
     })); 

     routes.Add("Default", new Route("{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), 
      DataTokens = defaultnamespace    
     }); 
    } 

唯一のもう1つの点は、ビューがベースディレクトリにまだあることを参照することです。そのため、ビューをディレクトリに配置して一致させる場合は、コントローラ内でビュー名を返す必要があります。

関連する問題