3

次のようなシナリオのルーティングの例またはサンプルを探しています。

処理の一般的な例: {controller}/{action}/{id}

したがって、ストアの製品検索を行うシナリオでは、次のようになります。

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

これを行ういくつかの店舗があり、一貫してそれを望んでいたとします。その場合、{category}/{controller}/{action}/{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 を使用するという考えです。または、一意のコントローラー名が必要であり、それらを配置する方法がありません。わずかに異なる名前空間/ディレクトリ?

編集して追加:

これが必要なもう 1 つの理由は、カテゴリを含む URL が必要な場合があり、特定のコントローラが特定のカテゴリでのみ機能するためです。

いいえ:

/this/search/items/search+term <-- 動作

/that/search/items/search+term <-- 検索コントローラーが許可されていないため、機能しません。

4

2 に答える 2

3

私は実際にそれを検索することによってではなく、この質問の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            
        });
    }

他の唯一のことは、ベースディレクトリにあるビューを参照することです。したがって、ビューを一致するディレクトリに配置する場合は、コントローラ内に返すときにビュー名を入力する必要があります。

于 2008-09-05T01:30:27.807 に答える
1

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

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

コードのアイデアを得るために、私がSOで答えたこの質問に関連するいくつかの質問がありますが、コントローラー名が同じになるため、これはある程度異なります。参考のためにリンクを含めました。

別のルートですが、いくつかの妥協が必要な場合がありますが、新しいAcceptVerbs属性を使用することです。詳細については、この質問を確認してください。この新機能はまだ試していませんが、別の方法である可能性があります。

于 2008-09-04T12:24:28.180 に答える