WebApi - Lier de deux Uri et du Corps
Est-il possible de lier un modèle à partir de l'Uri et le Corps?
Par exemple, le suivant:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
public class ProductsController : ApiController
{
public HttpResponseMessage Put(UpdateProduct model)
{
}
}
public class UpdateProduct
{
int Id { get; set;}
string Name { get; set; }
}
Est-il possible de créer un liant de façon qu'un PUT
à
/api/produits/1
avec un JSON corps de:
{
"Name": "Product Name"
}
entraînera la UpdateProduct
modèle rempli avec Id = 1
et Name = "Product Name"
?
Mise à jour
Je comprends que je pourrais modifier l'action de signature à
public HttpResponseMessage Put(int id, UpdateProduct model)
{
}
Cependant, comme indiqué dans la question, j'ai particulièrement envie de se lier à un seul modèle d'objet
J'ai aussi posté cette question sur le WebApi Codeplex forum de discussion
- Si vous supprimez le
Id
deUpdateProduct
et à votre action de signature:public HttpResponseMessage Put(int id, UpdateProduct model)
il serait également travailler sans modèle de liaison personnalisé. - Découvrez cet article, il semble que ce soit ce dont vous avez besoin: blogs.msdn.com/b/jmstall/archive/2012/04/18/...
- Avez-vous jamais trouver une solution à cela? Je vais avoir le même problème. À mon avis, c'est vraiment stupide et peu intuitive comportement.
- Complètement pas intuitive du comportement... surtout que ça fonctionne, tout simplement en MVC...
Vous devez vous connecter pour publier un commentaire.
Voici une version améliorée de odyth de réponse:
Par souci de concision, je viens de poster le ExecuteBindingAsyncCore méthode et une nouvelle auxiliaire de la méthode, le reste de la classe est la même.
IRequest<>
(Jimmy Bogard du Médiateur motif), qui contiennent tous les paramètres en un seul objet. Serait génial d'être en mesure de remplir à la fois les corps et les paramètres uri.ParameterBindingAttribute
à utiliser commepublic IHttpActionResult Put([FromUriAndBody]ComplexType param)
System.Web.HttpUtility
a besoin d'une référence àSystem.Web
, qui est redondante dans un projet d'API Web. Il a été suggéré d'utiliserSystem.Net.Http.UriExtensions.ParseQueryString()
. Donc le code dans QueryStringValues() doit être:var queryStringValues = request.RequestUri.ParseQueryString();
...[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)] public sealed class FromStuffAttribute : ParameterBindingAttribute { public override HttpParameterBinding GetBinding(HttpParameterDescriptor descriptor) { return new BodyAndUriParameterBinding(descriptor); } }
Êtes-vous toujours en l'utilisant? Courir dans toutes les questions?Vous pouvez définir votre propre DefaultActionValueBinder. Ensuite, vous pouvez mélanger et assortir à partir du corps et de l'uri. Voici un blog avec un exemple de MvcActionValueBinder pour les Api Web. Faire votre propre DefaultActionValueBinderis une solution privilégiée car elle garantit le classeur de ont fini avant les autres ActionFilterAttribute sont exécutées.
http://blogs.msdn.com/b/jmstall/archive/2012/04/18/mvc-style-parameter-binding-for-webapi.aspx
Mise à JOUR:
J'ai eu quelques difficultés avec la mise en œuvre dans le billet de blog et essayer de l'obtenir à utiliser mon support personnalisé formateurs. Heureusement, tous mes objets de demande de prolonger d'une classe de base donc j'ai fait mon propre formateur.
dans WebApiConfig
BodyAndUriParameterBinding.cs
Bien, je suis venu avec une façon de le faire. En gros, j'ai fait une action de filtre qui sera exécuté après le modèle a été peuplée à partir de JSON. Il se penchera ensuite sur les paramètres de l'URL, et définir les propriétés du modèle. Source complet ci-dessous:
Si je vous ai compris, cela devrait fonctionner hors de la boîte, par exemple, cela fonctionne pour moi:
et à la demande: localhost:56329/Home/Test/22
avec le corps:{"Nom":"outil"}
J'ai mon propriétés du modèle défini en conséquence à 22 et "outil".