web-dev-qa-db-fra.com

Comment récupérer les valeurs de corps d'un HTTP POST demande dans une API Web ASP.NET ValueProvider?

Je souhaite envoyer une demande HTTP POST avec le corps contenant des informations qui constituent un simple post de blog, rien d'extraordinaire.

J'ai lu ici que lorsque vous voulez lier un type complexe (c'est-à-dire un type qui n'est pas string, int etc.) dans l'API Web, une bonne approche consiste à créer un classeur de modèle personnalisé.

J'ai un classeur de modèle personnalisé (BlogPostModelBinder) qui utilise à son tour un fournisseur de valeurs personnalisé (BlogPostValueProvider). Ce que je ne comprends pas, c’est que comment et où puis-je récupérer les données du corps de la demande dans la variable BlogPostValueProvider?

À l’intérieur du classeur, c’est ce qui, à mon avis, serait un bon moyen de récupérer le titre, par exemple.

public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
   ...
   var title= bindingContext.ValueProvider.GetValue("Title");
   ...
}

alors que BlogPostValueProvider ressemble à ceci:

 public class BlogPostValueProvider : IValueProvider
 {
    public BlogPostValueProvider(HttpActionContext actionContext)
    {
       // I can find request header information in the actionContext, but not the body.
    }

    public ValueProviderResult GetValue(string key)
    {
       // In some way return the value from the body with the given key.
    }
 }

Cela pourrait être résolu de manière plus simple, mais comme je suis en train d’explorer des API Web, il serait bien de le faire fonctionner.

Mon problème est simplement que je ne peux pas trouver où le corps de la demande est stocké.

Merci pour tout conseil!

12
Jim Aho

Voici un article de blog à propos de Rick Strahl. Son message répond presque à votre question. Pour adapter son code à vos besoins, procédez comme suit.

Dans le constructeur de votre fournisseur de valeur, lisez le corps de la requête comme suit.

Task<string> content = actionContext.Request.Content.ReadAsStringAsync();
string body = content.Result;
19
Alex

J'avais besoin de faire cela dans un ActionFilterAttribute pour la journalisation, et la solution que j'ai trouvée consistait à utiliser les ActionArguments dans le champ actionContext comme dans

public class ExternalApiTraceAttribute : ActionFilterAttribute
{


    public override void OnActionExecuting(HttpActionContext actionContext)
    {
       ...

        var externalApiAudit = new ExternalApiAudit()
        {

            Method = actionContext.Request.Method.ToString(),
            RequestPath = actionContext.Request.RequestUri.AbsolutePath,
            IpAddresss = ((HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"]).Request.UserHostAddress,
            DateOccurred = DateTime.UtcNow,
            Arguments = Serialize(actionContext.ActionArguments)
        };
0
ColinM