2010-11-24 12 views
4

マイMVC2アプリケーションは、後続のAJAXバックサーバー上の不要なデータアクセスと処理のすべての種類を引き起こす同じアクションに呼び出しを行うコンポーネントを使用します。コンポーネントベンダーは、後続のリクエストを別のアクションにリルートすることを提案します。後続のリクエストは、特定のクエリ文字列を持っている点で異なり、私は自分のルートテーブルのクエリ文字列に制約を付けることができるかどうかを知りたいと思っています。例えばMVC2アプリでクエリ文字列パラメータのルート制約を指定できますか?

、最初の要求はhttp://localhost/document/display/1のようなURLでいます。これはデフォルトルートで処理できます。私は、URLに「ベンダー」を検出することにより、http://localhost/document/display/1?vendorParam1=blah1&script=blah.jshttp://localhost/document/display/1?vendorParam2=blah2&script=blah.jsのようなURLを処理するためのカスタムルートを書きたいです。

私は次のことを試してみましたが、それはSystem.ArgumentException: The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.をスロー:

routes.MapRoute(
    null, 
    "Document/Display/{id}?{args}", 
    new { controller = "OtherController", action = "OtherAction" }, 
    new RouteValueDictionary { { "args", "vendor" } }); 

私は、アカウントにクエリ文字列を取るルートを書くことができますか?そうでない場合は、他のアイデアはありますか?


更新:は、私はhttp://localhost/document/display/1DocumentController.Displayアクションにルーティングされますが、http://localhost/document/display/1?vendorParam1=blah1&script=blah.jsVendorController.Displayアクションにルーティングされるように、ルーティング制約を記述することができ、簡単に言えば?最終的には、クエリ文字列に "vendor"が含まれているURLをVendorController.Displayアクションにルーティングするようにしたいと思います。

私は最初のURLがデフォルトルートによって処理することができます理解しますが、何秒でしょうか?これをすべて行うことは可能ですか?試行錯誤の後、答えは「いいえ」と思われます。

答えて

9

のQueryStringはそれがデフォルトでサポートされていないものの、、制約で使用できるパラメータ。 Here ASP.NET MVC 2でこれを実装する方法を説明した記事を見つけることができます。

これはオランダ語で書いてありますので、ここで実装します。「IRouteConstraint」クラスを追加します。

public class QueryStringConstraint : IRouteConstraint 
{ 
    private readonly Regex _regex; 

    public QueryStringConstraint(string regex) 
    { 
     _regex = new Regex(regex, RegexOptions.IgnoreCase); 
    } 

    public bool Match (HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     // check whether the paramname is in the QS collection 
     if(httpContext.Request.QueryString.AllKeys.Contains(parameterName)) 
     { 
      // validate on the given regex 
      return _regex.Match(httpContext.Request.QueryString[parameterName]).Success; 
     } 
     // or return false 
     return false; 
    } 
} 

今すぐあなたのルートでこれを使用することができます。

routes.MapRoute("object-contact", 
    "{aanbod}", 
    /* ... */, 
    new { pagina = new QueryStringConstraint("some|constraint") }); 
+0

ありがとう、Jan.私はこのことを詳しく見ています。フォローアップとして、MVC 3のためにこれを変更しますか? – flipdoubt

+0

いいえ、これはMVC 3でもうまくいくと私は確信しています。これは、Microsoft実装のかなり基本的な概念です。 ASP.NETは実際には実際のファイルにマップされていない10.000.000の異なるURLをASP.NETが好まないため、これを使用します。 –

2

あなたは、このためのルートは必要ありません。既定のモデルバインダーによって既に処理されています。クエリ文字列パラメータを自動的にアクションの引数にバインドされます。

public ActionResult Foo(string id, string script, string vendorname) 
{ 
    // the id parameter will be bound from the default route token 
    // script and vendorname parameters will be bound from the request string 
    ...  
} 

はUPDATE:

あなたがそれらをループ可能性が渡されるクエリ文字列パラメータの名前がわからない場合:

foreach (string key in Request.QueryString.Keys) 
{ 
    string value = Request.QueryString[key]; 
} 
+0

ありがとう、ダーリン、しかし、私が投稿したサンプルコードは、要求を別のコントローラに再ルーティングしたいと考えています。また、このコンポーネントは、複数の後続のリクエストを作成します。それぞれのリクエストには異なるパラメータが使用され、いくつかのパラメータにはベンダー名の接頭辞が付けられます。 – flipdoubt

+0

@flipdoubt、渡されるクエリ文字列パラメータの名前がわからない場合は、それらをループすることができます。あなたのルートは次のようになります: 'routes.MapRoute(null、" Document/Display/{id} "、new {controller =" OtherController "、action =" OtherAction "}); –

+0

「いいえ、クエリ文字列パラメータは経路制約に使用できません」と言っていますか? – flipdoubt

-1

この投稿は古いですが、あなたはデフォルトルート

前にルートを作成することができませんでした

これは、args内の "vendor"を持つ経路だけをキャッチします。

routes.MapRoute(
    null, 
    "Document/Display/{id}?{args}", 
    new { controller = "VendorController", action = "OtherAction" }, 
    new {[email protected]".*(vendor).*"}//believe this is correct regex to catch "vendor" anywhere in the args 

、これは残り

routes.MapRoute(
     null, 
     "Document/Display/{id}?{args}", 
     new { controller = "DisplayController", action = "OtherAction" } 
    ); 

はこれを試したことがないと私はMVCの初心者ですが、私は、これは動作するはずと信じ??キャッチします制約が一致しない場合は、ルートが使用されていないことがわかります。それで、次のルートをテストします。あなたの次のルートはargsに制約を使用しないので、それはルートと一致する必要があります。

私はこれを試してみて、それは私のために働いた。

+1

ルートURLに '?'を含めることはできません。キャラクター。 – Softlion

関連する問題