私のwebapiプロジェクトには次のルート定義があります。パラメータの1つが渡されないという問題があります。例えば;
/ Controller/Action/param2/startdate/enddateを呼び出すと、param2に渡した値がparam1に使用され、その逆も同様です。問題は、RoutingModuleが、指定されたルート値がparam1ではなくparam2にあることを検出できないことです。
URLでクエリ文字列を使用しているがクエリ文字列を使用したくない場合は機能します。あなたの助けに感謝。
私が期待することを達成する方法はありますか?
config.Routes.MapHttpRoute(
name: "RetrieveHistory",
routeTemplate: "{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}",
defaults: new
{
controller = "Vend",
action = "RetrieveUtrnHistory",
param1 = RouteParameter.Optional,
param2 = RouteParameter.Optional,
starDate = RouteParameter.Optional,
endDate = RouteParameter.Optional
});
ありがとう
問題を解決するには、次のことを考慮に入れる必要があります。
/
以外のものを区切り文字として使用して、ルートの一部を区別できるようにすることができますURLがどのように見えるかを教えてくれなかったので、私自身の例を紹介します。
次のようなアクションを持つTestController
WebAPIコントローラークラスがあるとします。
// GET api/Test/TestAction/ ...
[HttpGet]
public object TestAction(int param1, DateTime startDate, DateTime endDate,
int? param2 = null)
{
return new
{
param1 = param1,
param2 = param2,
startDate = startDate,
endDate = endDate
}.ToString();
}
注:デフォルトルートでは、GetXxx
という名前のWebAPIコントローラーのメソッドがHTTPGETで使用でき、PostXxx
という名前のメソッドがHTTPで使用できますPOST =など。ただし、URLテンプレートにController
とAction
を含めたら、[HttpXxx]
属性を使用して、必要なHTTPメソッドでメソッドを使用できるようにする必要があります。
この最初の例では、param1
とparam2
の両方が整数であり、stardDate
とendDate
が日付であると想定しています。
http://myhost/api/Mycontroller/Myaction/12/22/2014-12-01/2014-12-31
http://myhost/api/Mycontroller/Myaction/22/2014-12-01/2014-12-31
最初のURLを次のようなパラメータに一致させる場合:
param1 = 12; param2 = 22; startDate = 2014-12-01; endData = 2014-12-31
そしてこれらのような2番目:
param1 = 12; param2 = null; startDate = 2014-12-01; endData = 2014-12-31
2つのルートを登録する必要があります。1つは可能な各URL構造に一致します。
// for the 1st
routeTemplate: "api/{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}"
// for the 2nd
routeTemplate: "api/{controller}/{action}/{param1}/{startDate}/{endDate}"
この場合、両方のルートは相互に排他的であることに注意してください。つまり、単一のURLは一方のルートにのみ一致するため、他のルートに登録できます。
ただし、2番目のURLはparam2
の値を定義しておらず、TestAction
メソッドはそれを必要とすることに注意する必要があります。これは機能しません。コントローラーのメソッドとルート登録の両方に、このパラメーターのデフォルト値を含める必要があります。
int? param2 = null
(C#ではオプションのパラメータを最後にする必要があります)。defaults: new { param2 = RouteParameter.Optional }
これは、真ん中の問題のオプションのパラメータを解決する方法です。一般に、オプションのパラメーターの数に応じていくつかのルートを定義し、WebAPIアクションメソッドでこのパラメーターをデフォルト値で宣言する必要があります。
注:上記で書いたように、MVCでは、これを機能させるためにメソッドパラメーターにデフォルト値を指定する必要はありません。
ルートパラメータに制約を指定すると、次の2つの結果が生じます。
次のように、ルート登録にconstraint
パラメータを追加するだけです。
config.Routes.MapHttpRoute(
name: "Multiparam2",
routeTemplate: "api/{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}",
constraints: new
{
startDate = @"20\d\d-[0-1]?\d-[0-3]?\d", // regex
endDate = @"20\d\d-[0-1]?\d-[0-3]?\d" // regex
},
defaults: new object { }
);
空の場合でも、defaults
パラメーターを指定する必要があることに注意してください。
注:この場合の制約は、20XX年の日付、1桁、または0xまたは1xとして表される月、および1桁または0x、1x、2xとして表される日付にのみ一致する正規表現です。または3x、ダッシュで区切ります。したがって、この正規表現は2012-1-1
または2015-12-30
と一致しますが、1920-12-30
とは一致しません。必要に応じて正規表現を調整する必要があります。
この時点で、オプションのパラメーターをサポートする方法と、ルートテンプレートに一致するようにそれらの形式(制約)を指定する方法について説明しました。
オプションのパラメータを定義する通常の方法は、URLテンプレートの最後で行うことです。この場合、ルートにパラメータがない場合は、すべてルートの最後にある必要があります。 (これを中央のオプションと比較してください:異なるルートが必要です)。
この例で、オプションのparam2
、およびstartDate
とendDate
を作成する場合は、ルート登録でそれらを定義し、アクションでデフォルトのパラメーター値を設定する必要があります。方法。
最終的なコードは次のようになります。
[HttpGet]
public object TestAction(int param1, int? param2 = null, DateTime? startDate = null,
DateTime? endDate = null)
{
return new
{
param1 = param1,
param2 = param2,
startDate = startDate,
endDate = endDate
}.ToString();
}
config.Routes.MapHttpRoute(
name: "Multiparam1",
routeTemplate: "api/{controller}/{action}/{param1}/{startDate}/{endDate}",
constraints: new
{
startDate = @"20\d\d-[0-1]?\d-[0-3]?\d",
endDate = @"20\d\d-[0-1]?\d-[0-3]?\d"
},
defaults: new
{
param2 = RouteParameter.Optional,
startDate = RouteParameter.Optional,
endDate = RouteParameter.Optional
}
);
config.Routes.MapHttpRoute(
name: "Multiparam2",
routeTemplate: "api/{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}",
constraints: new
{
startDate = @"(20\d\d-[0-1]?\d-[0-3]?\d)?",
endDate = @"(20\d\d-[0-1]?\d-[0-3]?\d)?"
},
defaults: new
{
startDate = RouteParameter.Optional,
endDate = RouteParameter.Optional
}
);
この場合、次のことに注意してください。
Multiparam2
ルートを登録した場合、次のようなURLが誤って処理されます:http://localhost:1179/api/test/testaction/1/2014-12-12/2015-1-1
、param1=1; param2="2014-12-12"; startDate="2015-1-1"
。 (param2=@"\d+"
のように、数値のみを受け入れるparam2に追加の制約を設定することで、これを回避できます)startDate
およびendDate
のデフォルト値が必要です。慎重に、さまざまな位置でデフォルトパラメータを処理できます。
ルートがどのように見えるかを慎重に計画すると、いくつかのルートとオプションのパラメーターを使用して必要なものを取得できます。
JotaBeの答えは素晴らしく完全でした。パラメータがオプションであるかどうかを考慮する必要があります。最も低いパラメータから最も高いパラメータの順にrouteTemplateを記述する必要があります。
と同じように :
// for the 1st
routeTemplate: "api/{controller}/{action}/{param1}/{startDate}/{endDate}"
// for the 2nd
routeTemplate: "api/{controller}/{action}/{param1}/{param2}/{startDate}/{endDate}"