Warum werden die Attribute FromBody
und FromUri
in der ASP.NET-Web-API benötigt?
Was sind die Unterschiede zwischen der Verwendung der Attribute und der Nichtverwendung?
Warum werden die Attribute FromBody
und FromUri
in der ASP.NET-Web-API benötigt?
Was sind die Unterschiede zwischen der Verwendung der Attribute und der Nichtverwendung?
Antworten:
Wenn die ASP.NET-Web-API eine Methode auf einem Controller aufruft, muss sie Werte für die Parameter festlegen, ein Prozess, der als Parameterbindung bezeichnet wird .
Standardmäßig verwendet die Web-API die folgenden Regeln, um Parameter zu binden:
Wenn der Parameter ein "einfacher" Typ ist , versucht die Web-API, den Wert vom URI abzurufen . Zu den einfachen Typen gehören die primitiven .NET-Typen (int, bool, double usw.) sowie TimeSpan, DateTime, Guid, decimal und string sowie alle Typen mit einem Typkonverter, der aus einer Zeichenfolge konvertiert werden kann.
Bei komplexen Typen versucht die Web-API, den Wert mithilfe eines Medientyp-Formatierers aus dem Nachrichtentext zu lesen .
Wenn Sie also das oben genannte Standardverhalten überschreiben und die Web-API zwingen möchten, einen komplexen Typ aus dem URI zu lesen, fügen Sie das [FromUri]
Attribut dem Parameter hinzu. Fügen Sie das [FromBody]
Attribut dem Parameter hinzu, um die Web-API zu zwingen, einen einfachen Typ aus dem Anforderungshauptteil zu lesen .
Um Ihre Frage zu beantworten, müssen die Attribute [FromBody]
und [FromUri]
in der Web-API einfach das oben beschriebene Standardverhalten überschreiben, falls erforderlich. Beachten Sie, dass Sie beide Attribute für eine Controller-Methode verwenden können, jedoch nur für verschiedene Parameter, wie hier gezeigt .
Es gibt viel mehr Informationen im Web, wenn Sie "Web-API-Parameterbindung" googeln.
JustGetIt
[FromBody, FromQuery]
Das Standardverhalten ist:
Wenn die Parameter a primitive Art ( int
, bool
, double
, ...), Web - API versucht , den Wert von der zu bekommen URI der HTTPAnforderung.
Bei komplexen Typen (z. B. Ihrem eigenen Objekt Person
:) versucht die Web-API, den Wert aus dem zu lesen Hauptteil der HTTP-Anforderung.
Also, wenn Sie haben:
... dann müssen Sie keine Attribute hinzufügen (auch nicht [FromBody]
noch [FromUri]
).
Aber wenn Sie einen primitiven Typ im Körper haben , müssen Sie ihn [FromBody]
in Ihrer WebAPI-Controller-Methode vor Ihrem primitiven Typparameter hinzufügen . (Da WebAPI standardmäßig nach primitiven Typen im URI der HTTP-Anforderung sucht.)
Wenn Sie einen komplexen Typ in Ihrer URI haben , müssen Sie diesen hinzufügen[FromUri]
. (Da WebAPI standardmäßig nach komplexen Typen im Hauptteil der HTTP-Anforderung sucht.)
Primitive Typen:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post([FromBody]int id)
{
}
// api/users/id
public HttpResponseMessage Post(int id)
{
}
}
Komplexe Typen:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post(User user)
{
}
// api/users/user
public HttpResponseMessage Post([FromUri]User user)
{
}
}
Dies funktioniert, solange Sie nur einen Parameter in Ihrer HTTP-Anfrage senden . Wenn Sie mehrere senden , müssen Sie ein benutzerdefiniertes Modell erstellen,das alle Ihre Parameter wie folgt enthält:
public class MyModel
{
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
}
[Route("search")]
[HttpPost]
public async Task<dynamic> Search([FromBody] MyModel model)
{
// model.MyProperty;
// model.MyProperty2;
}
Aus der Microsoft-Dokumentation zur Parameterbindung in der ASP.NET-Web-API :
Wenn ein Parameter [FromBody] hat, verwendet die Web-API den Content-Type-Header, um einen Formatierer auszuwählen. In diesem Beispiel lautet der Inhaltstyp "application / json" und der Anforderungshauptteil ist eine unformatierte JSON-Zeichenfolge (kein JSON-Objekt). Es darf höchstens ein Parameter aus dem Nachrichtentext lesen.
Das sollte funktionieren:
public HttpResponseMessage Post([FromBody] string name) { ... }
Dies wird nicht funktionieren:
// Caution: This won't work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Der Grund für diese Regel ist, dass der Anforderungshauptteil möglicherweise in einem nicht gepufferten Stream gespeichert ist, der nur einmal gelesen werden kann.
Nur Ergänzung zu den obigen Antworten ..
[FromUri] kann auch verwendet werden, um komplexe Typen aus Uri-Parametern zu binden, anstatt Parameter aus Querystring zu übergeben
Zum Beispiel ..
public class GeoPoint
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
[RoutePrefix("api/Values")]
public ValuesController : ApiController
{
[Route("{Latitude}/{Longitude}")]
public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
}
Kann wie folgt aufgerufen werden:
http://localhost/api/values/47.678558/-122.130989
Wenn ein Parameter [FromBody] hat, verwendet die Web-API den Content-Type-Header, um einen Formatierer auszuwählen. In diesem Beispiel lautet der Inhaltstyp "application / json" und der Anforderungshauptteil ist eine unformatierte JSON-Zeichenfolge (kein JSON-Objekt).
Es darf höchstens ein Parameter aus dem Nachrichtentext lesen. Das wird also nicht funktionieren:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Der Grund für diese Regel ist, dass der Anforderungshauptteil möglicherweise in einem nicht gepufferten Stream gespeichert ist, der nur einmal gelesen werden kann
Weitere Informationen finden Sie auf der Website: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api