wake-up-neo.com

Optionale Parameter im Web-API-Attributrouting

Ich möchte POST des folgenden API-Aufrufs behandeln:

/v1/location/deviceid/appid

Zusätzliche Parameter kommen vom Post-Body.

Das alles funktioniert gut für mich. Jetzt möchte ich meinen Code erweitern, indem ich zulasse, dass "deviceid" und/oder "appid" und/oder BodyData null sind:

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

Diese drei URLs sollten auf demselben Weg beantwortet werden.

Mein erster Ansatz (BodyData erforderlich):

[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);
}

Dies funktioniert nicht und gibt einen Kompilierungsfehler zurück:

"optionale Parameter müssen am Ende stehen"

Nächster Versuch:

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

Jetzt bekommt meine Funktion AddNewLocation () immer ein BodyData=null - auch wenn der Anruf den Body sendet.

Zum Schluss habe ich alle 3 Parameter optional gesetzt:

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

Funktioniert nicht

Der optionale Parameter BodyData wird von FormatterParameterBinding nicht unterstützt.

Warum möchte ich eine Lösung mit optionalen Parametern? Mein Controller übernimmt lediglich das "Hinzufügen eines neuen Standorts" über einen POST.

Ich möchte bei falschen Daten meine eigenen Ausnahmen oder Fehlermeldungen senden. Auch wenn der Aufruf fehlende Werte hat. In diesem Fall möchte ich in der Lage sein, eine Ausnahme oder das Festlegen von Standardwerten durch meinen Code auszulösen.

80
Oliver Apel

Wie Sie sich vorstellen können, ist es für eine eingehende Anfrage wie /v1/location/1234 Für die Web-API schwierig, automatisch herauszufinden, ob der Wert des Segments, das '1234' entspricht, mit appid zusammenhängt und nicht mit deviceid.

Ich denke, Sie sollten Ihre Routenvorlage so ändern, dass sie wie [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")] aussieht, und dann das deiveOrAppid analysieren, um den Typ der ID herauszufinden.

Außerdem müssen Sie die Segmente in der Routenvorlage selbst optional machen, da sonst die Segmente als erforderlich betrachtet werden. Beachten Sie in diesem Fall das Zeichen ?. Zum Beispiel: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]

153
Kiran Challa

Noch eine Info: Wenn Sie eine Route Constraint verwenden möchten, stellen Sie sich vor, dass Sie erzwingen möchten, dass dieser Parameter int Datentyp hat, dann müssen Sie diese Syntax verwenden:

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

Das Zeichen ? steht immer vor dem letzten Zeichen }

Weitere Informationen finden Sie unter: Optionale URI-Parameter und Standardwerte

42
Tiago Ferreira

Mein Kommentar in eine Antwort umwandeln, um die Antwort von @Kiran Chala zu ergänzen, da sie für das Publikum hilfreich zu sein scheint -

Wenn wir einen Parameter in der Aktion uri mit dem Zeichen ? Als optional markieren, müssen wir die Parameter in der Methodensignatur wie folgt mit Standardwerten versehen:

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

14
RBT