web-dev-qa-db-ja.com

Web API属性ルーティングのオプションパラメーター

次のAPI呼び出しのPOSTを処理したい:

/v1/location/deviceid/appid

追加パラメーターは、ポストボディから取得されます。

これはすべて私にとってうまく機能します。ここで、「deviceid」および/または「appid」および/またはBodyDataをnullにすることでコードを拡張します。

/v1/location/deviceid
/v1/location/appid
/v1/location/

これら3つのURLは、同じルートで応答する必要があります。

私の最初のアプローチ(BodyDataが必要):

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody] location_fromuser BodyData)
{
    return repository.AddNewLocation(deviceid, appid, BodyData);
}

これは機能せず、コンパイルエラーを返します。

「オプションのパラメータは最後にある必要があります」

次の試行:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post([FromBody] location_fromuser BodyData, string deviceid = null, string appid = null)

これで、関数AddNewLocation()が常にBodyData=nullを取得します-呼び出しがBodyを送信した場合でも。

最後に、3つのパラメーターすべてをオプションとして設定します。

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody location_fromuser BodyData = null)

動作しない:

オプションのパラメータBodyDataは、FormatterParameterBindingではサポートされていません。

オプションのパラメーターを使用したソリューションが必要なのはなぜですか?私のコントローラーは、POSTを介して「新しい場所の追加」だけを処理します。

自分の例外やエラーメッセージを間違ったデータで送信したい。呼び出しに欠損値がある場合でも。この場合、例外をスローするか、コードでデフォルトを設定するかを決定できます。

80
Oliver Apel

/v1/location/1234のような着信リクエストの場合、「1234」に対応するセグメントの値がappidではなくdeviceidに関連しているかどうかをWeb APIが自動的に把握することは難しいと想像できます。

ルートテンプレートを[Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]のように変更し、deiveOrAppidを解析してIDのタイプを把握する必要があると思います。

また、ルートテンプレート自体のセグメントをオプションにする必要があります。そうでない場合、セグメントは必須と見なされます。この場合の?文字に注意してください。例:[Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]

150
Kiran Challa

別の情報:Route Constraintを使用する場合、そのパラメーターにintデータ型の場合、次の構文を使用する必要があります。

[Route("v1/location/**{deviceOrAppid:int?}**", Name = "AddNewLocation")]

文字は常に最後の}文字の前に置かれます

詳細については、以下を参照してください。 オプションのURIパラメーターとデフォルト値

41
Tiago Ferreira

@Kiran Chalaの回答を補完する回答に私のコメントを変換します

?文字を使用してアクションuriでパラメーターをオプションとしてマークする場合、以下に示すようにメソッドシグネチャのパラメーターにデフォルト値を提供する必要があります。

MyMethod(string name = "someDefaultValue", int? Id = null)

11
RBT