2014-04-05 11 views
12

Ich möchte eine HTTP-POST-Anfrage mit dem Körper senden, der Informationen enthält, die einen einfachen Blog-Post bilden, nichts Schickes.Wie kann ich Körperwerte aus einer HTTP-POST-Anforderung in einem ASP.NET-Web-API-ValueProvider abrufen?

Ich habe gelesen here, dass, wenn Sie einen komplexen Typ (das heißt eine Art, die nicht string ist, int etc.) binden möchten in Web-API, ein guter Ansatz ist es, ein benutzerdefiniertes Modell Bindemittel zu erstellen.

Ich habe ein benutzerdefiniertes Modell Bindemittel (BlogPostModelBinder), die wiederum einen benutzerdefinierten Value Provider (BlogPostValueProvider) verwendet. Was ich nicht verstehe ist, wie und wo soll ich die Daten aus dem Anfragetext in der BlogPostValueProvider abrufen können?

Innerhalb des Modellbinders dachte ich, dass dies der richtige Weg wäre, um beispielsweise den Titel wiederzufinden.

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

während die BlogPostValueProvider sieht wie folgt aus:

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. 
    } 
} 

Dieses in einen einfacheren Weg gelöst werden könnten, aber da ich bin Web-API zu erforschen wäre es schön, um es an die Arbeit.

Mein Problem ist einfach, dass ich nicht finden kann, wo der Anfragekörper gespeichert ist.

Danke für jede Anleitung!

+0

Was Ihre Anfrage Content-Typ ist ... ich bin angenommen formullencoded? ... könnten Sie mehr Details geben, warum Sie ein kundenspezifisches Modellmappe benötigen ... –

+0

Wenn Sie ein json von BlogPostVM bekanntgeben, dann benötigen Sie nur eine Aktion, die BlogPostVM, keine Notwendigkeit für kundenspezifische Mappen annimmt. –

+0

Ich denke, Sie sind beide richtig. Der ContentType in der Anfrage wird auf json @KiranChalla festgelegt. Eine Aktion mit einem Parameter vom Typ BlogPost könnte dies tun. Ich möchte immer noch wissen, warum ich nicht innerhalb des Value Providers auf den Body der Anfrage zugreifen kann. –

Antwort

15

Hier ist ein blog post darüber von Rick Strahl. Sein Beitrag beantwortet fast Ihre Frage. Um seinen Code an Ihre Bedürfnisse anzupassen, würden Sie Folgendes tun.

Lesen Sie im Konstruktor Ihres Value Providers den Anfragetext so.

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

Ich brauchte diese in einem Action für die Protokollierung zu tun, und die Lösung war ich gefunden, wie die ActionArguments in den Action zu verwenden, in

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) 
     };