Pourquoi les attributs FromBody
et sont-ils FromUri
nécessaires dans l'API Web ASP.NET`?
Quelles sont les différences entre utiliser les attributs et ne pas les utiliser?
Pourquoi les attributs FromBody
et sont-ils FromUri
nécessaires dans l'API Web ASP.NET`?
Quelles sont les différences entre utiliser les attributs et ne pas les utiliser?
Réponses:
Lorsque l'API Web ASP.NET appelle une méthode sur un contrôleur, elle doit définir des valeurs pour les paramètres, un processus appelé liaison de paramètres .
Par défaut, l'API Web utilise les règles suivantes pour lier les paramètres:
Si le paramètre est de type "simple" , l'API Web essaie d'obtenir la valeur de l'URI . Les types simples incluent les types primitifs .NET (int, bool, double, etc.), plus TimeSpan, DateTime, Guid, decimal et string, ainsi que tout type avec un convertisseur de type qui peut convertir à partir d'une chaîne.
Pour les types complexes , l'API Web tente de lire la valeur à partir du corps du message , à l'aide d'un formateur de type média.
Par conséquent, si vous souhaitez remplacer le comportement par défaut ci-dessus et forcer l'API Web à lire un type complexe à partir de l'URI, ajoutez l' [FromUri]
attribut au paramètre. Pour forcer l'API Web à lire un type simple à partir du corps de la requête, ajoutez l' [FromBody]
attribut au paramètre.
Donc, pour répondre à votre question, le besoin des attributs [FromBody]
et [FromUri]
dans l'API Web est simplement de remplacer, si nécessaire, le comportement par défaut décrit ci-dessus. Notez que vous pouvez utiliser les deux attributs pour une méthode de contrôleur, mais uniquement pour des paramètres différents, comme illustré ici .
Il y a beaucoup plus d' informations sur le Web si vous google "liaison de paramètre de l'API Web".
JustGetIt
qui sert le même but d'ajouter plusieurs attributs comme [FromBody, FromQuery]
etc
Le comportement par défaut est:
Si le paramètre est une primitive de type ( int
, bool
, double
, ...), l' API Web cherche à obtenir la valeur de l' URI de la requête HTTP.
Pour les types complexes (votre propre objet, par exemple Person
:), l'API Web essaie de lire la valeur à partir du corps de la requête HTTP.
Donc, si vous avez:
... alors vous n'avez pas à ajouter d'attributs (ni [FromBody]
ni [FromUri]
).
Mais, si vous avez un type primitif dans le corps , vous devez l'ajouter [FromBody]
devant votre paramètre de type primitif dans votre méthode de contrôleur WebAPI. (Parce que, par défaut, WebAPI recherche des types primitifs dans l'URI de la requête HTTP.)
Ou, si vous avez un type complexe dans votre URI , vous devez ajouter [FromUri]
. (Parce que, par défaut, WebAPI recherche par défaut des types complexes dans le corps de la requête HTTP.)
Types primitifs:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post([FromBody]int id)
{
}
// api/users/id
public HttpResponseMessage Post(int id)
{
}
}
Types complexes:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post(User user)
{
}
// api/users/user
public HttpResponseMessage Post([FromUri]User user)
{
}
}
Cela fonctionne tant que vous n'envoyez qu'un seul paramètre dans votre requête HTTP. Lors de l'envoi de plusieurs , vous devez créer un modèle personnalisé qui a tous vos paramètres comme ceci:
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;
}
À partir de la documentation de Microsoft pour la liaison de paramètres dans l'API Web ASP.NET :
Lorsqu'un paramètre a [FromBody], l'API Web utilise l'en-tête Content-Type pour sélectionner un formateur. Dans cet exemple, le type de contenu est "application / json" et le corps de la demande est une chaîne JSON brute (pas un objet JSON). Au plus un paramètre est autorisé à lire à partir du corps du message.
Cela devrait fonctionner:
public HttpResponseMessage Post([FromBody] string name) { ... }
Cela ne fonctionnera pas:
// Caution: This won't work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
La raison de cette règle est que le corps de la requête peut être stocké dans un flux non mis en mémoire tampon qui ne peut être lu qu'une seule fois.
Juste un ajout aux réponses ci-dessus.
[FromUri] peut également être utilisé pour lier des types complexes à partir de paramètres uri au lieu de passer des paramètres depuis une chaîne de requête
Pour 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) { ... }
}
Peut être appelé comme:
http://localhost/api/values/47.678558/-122.130989
Lorsqu'un paramètre a [FromBody], l'API Web utilise l'en-tête Content-Type pour sélectionner un formateur. Dans cet exemple, le type de contenu est "application / json" et le corps de la demande est une chaîne JSON brute (pas un objet JSON).
Au plus un paramètre est autorisé à lire à partir du corps du message. Donc cela ne fonctionnera pas:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
La raison de cette règle est que le corps de la requête peut être stocké dans un flux non tamponné qui ne peut être lu qu'une seule fois
Veuillez consulter le site Web pour plus de détails: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api