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 vonFormatterParameterBinding
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.
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")]
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
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)