Perché gli attributi FromBody
e sono FromUri
necessari nell'API Web ASP.NET`?
Quali sono le differenze tra usare gli attributi e non usarli?
Perché gli attributi FromBody
e sono FromUri
necessari nell'API Web ASP.NET`?
Quali sono le differenze tra usare gli attributi e non usarli?
Risposte:
Quando l'API Web ASP.NET chiama un metodo su un controller, deve impostare i valori per i parametri, un processo chiamato binding dei parametri .
Per impostazione predefinita, l'API Web utilizza le seguenti regole per associare i parametri:
Se il parametro è di tipo "semplice" , l'API Web tenta di ottenere il valore dall'URI . I tipi semplici includono i tipi primitivi .NET (int, bool, double e così via), più TimeSpan, DateTime, Guid, decimale e stringa, oltre a qualsiasi tipo con un convertitore di tipi che può convertire da una stringa.
Per tipi complessi , l'API Web tenta di leggere il valore dal corpo del messaggio , utilizzando un formattatore di tipo multimediale.
Pertanto, se si desidera sovrascrivere il comportamento predefinito sopra riportato e forzare l'API Web a leggere un tipo complesso dall'URI, aggiungere l' [FromUri]
attributo al parametro. Per forzare l'API Web a leggere un tipo semplice dal corpo della richiesta, aggiungere l' [FromBody]
attributo al parametro.
Quindi, per rispondere alla tua domanda, la necessità degli attributi [FromBody]
e [FromUri]
nell'API Web è semplicemente quella di sovrascrivere, se necessario, il comportamento predefinito come descritto sopra. Si noti che è possibile utilizzare entrambi gli attributi per un metodo controller, ma solo per parametri diversi, come dimostrato qui .
Ci sono molte più informazioni sul web se si google "associazione parametri web api".
JustGetIt
che serve allo stesso scopo di aggiungere più attributi come [FromBody, FromQuery]
ecc.
Il comportamento predefinito è:
Se il parametro è un primitivo tipo ( int
, bool
, double
, ...), cerca Web API per ottenere il valore dal URI della richiesta HTTP.
Per tipi complessi (il tuo oggetto, ad esempio:) Person
, l'API Web tenta di leggere il valore dal corpo della richiesta HTTP.
Quindi, se hai:
... quindi non è necessario aggiungere alcun attributo (né [FromBody]
né né [FromUri]
).
Ma se hai un tipo primitivo nel corpo , devi aggiungere [FromBody]
davanti al parametro del tipo primitivo nel metodo del controller WebAPI. (Perché, per impostazione predefinita, WebAPI è alla ricerca di tipi primitivi nell'URI della richiesta HTTP.)
Oppure, se hai un tipo complesso nel tuo URI , devi aggiungere [FromUri]
. (Perché, per impostazione predefinita, WebAPI è alla ricerca di tipi complessi nel corpo della richiesta HTTP per impostazione predefinita.)
Tipi primitivi:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post([FromBody]int id)
{
}
// api/users/id
public HttpResponseMessage Post(int id)
{
}
}
Tipi complessi:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post(User user)
{
}
// api/users/user
public HttpResponseMessage Post([FromUri]User user)
{
}
}
Funziona finché si invia un solo parametro nella richiesta HTTP. Quando si inviano più , è necessario creare un modello personalizzato con tutti i parametri come questo:
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;
}
Dalla documentazione di Microsoft per l' associazione dei parametri nell'API Web ASP.NET :
Quando un parametro ha [FromBody], l'API Web utilizza l'intestazione Content-Type per selezionare un formattatore. In questo esempio, il tipo di contenuto è "application / json" e il corpo della richiesta è una stringa JSON non elaborata (non un oggetto JSON). Al massimo un parametro può leggere dal corpo del messaggio.
Questo dovrebbe funzionare:
public HttpResponseMessage Post([FromBody] string name) { ... }
Questo non funzionerà:
// Caution: This won't work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Il motivo di questa regola è che il corpo della richiesta potrebbe essere archiviato in un flusso senza buffer che può essere letto solo una volta.
Solo aggiunta alle risposte sopra ..
[FromUri] può anche essere usato per legare tipi complessi da parametri uri invece di passare parametri da querystring
Per Ex ..
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) { ... }
}
Può essere chiamato come:
http://localhost/api/values/47.678558/-122.130989
Quando un parametro ha [FromBody], l'API Web utilizza l'intestazione Content-Type per selezionare un formattatore. In questo esempio, il tipo di contenuto è "application / json" e il corpo della richiesta è una stringa JSON non elaborata (non un oggetto JSON).
Al massimo un parametro può leggere dal corpo del messaggio. Quindi questo non funzionerà:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
Il motivo di questa regola è che il corpo della richiesta potrebbe essere archiviato in un flusso senza buffer che può essere letto solo una volta
Per ulteriori dettagli, visitare il sito Web: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api