14 Stimmen

Kann Körperdaten von Web-Api-POST nicht lesen

Ich versuche, einige Daten aus einer Anforderung in der neuen Asp.Net Web Api zu extrahieren. Ich habe ein Handler-Setup wie folgt:

public class MyTestHandler : DelegatingHandler
{
    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        if (request.Content.IsFormData())
        {
            request.Content.ReadAsStreamAsync().ContinueWith(x => {
                var result = "";
                using (var sr = new StreamReader(x.Result))
                {
                    result = sr.ReadToEnd();
                }
                Console.Write(result);
            });
        }

        return base.SendAsync(request, cancellationToken);
    }
}

Dies ist meine http-Anfrage:

POST http://127.0.0.1/test HTTP/1.1
Connection: Keep-Alive
Content-Length: 29
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue
Host: 127.0.0.1

my_property=my_value

Das Problem ist, dass ich, egal wie ich versuche, die Informationen aus request.Content sie ist immer leer. Ich habe versucht

request.Content.ReadAsStreamAsync
request.Content.ReadAsFormDataAsync
request.Content.ReadAs<FormDataCollection>

wie auch

    [HttpGet,HttpPost]
    public string Index([FromBody]string my_property)
    {
        //my_property == null
        return "Test";
    }

Nicht, wenn es funktioniert. Ich kann die Daten nicht aus dem Body herausbekommen. Ich hoste innerhalb von IIS auf Windows 7 und verwende Fiddler, um die Anfrage zu übermitteln. Was mache ich falsch?

20voto

Micah Punkte 106323

Das Problem ist, dass mit der Web Api der Body nur einmal gelesen werden kann. Ich hatte ein HTTP-Modul laufen, die alle Details der Anforderung protokolliert wurde und wurde durch den Körper lesen.

7voto

brmore Punkte 896

Es ist hässlich, aber Sie scheint es von ersten Basteln, dass Sie in der Tat, ersetzen Sie den Inhalt in DelegatingHandler ...

protected override Task SendAsync(
          HttpRequestMessage request,
          CancellationToken cancellationToken)
      {                    
          Stream stream = new MemoryStream();

          request.Content.ReadAsStreamAsync().Result.CopyTo(stream);
          stream.Seek(0,SeekOrigin.Begin);

          // copy off the content "for later"
          string query = new StreamReader(stream).ReadToEnd();
          stream.Seek(0,SeekOrigin.Begin);

          // if further processing depends on content type
          // go ahead and grab current value
          var contentType = request.Content.Headers.ContentType;

          request.Content = new StreamContent(stream);
          request.Content.Headers.ContentType = contentType;

          return base.SendAsync(request, cancellationToken);
     }

Ich habe keine Ahnung, ob dies eine gute Form oder schlecht ist (vermutlich schlecht), aber .... es scheint zu funktionieren und folgt Modell, das ich gesehen habe, empfohlen für diejenigen, die Anfrage-Header und Inhalt "auf dem Weg in" mit einem DelegatingHandler ändern müssen.

Ihr Kilometerstand kann stark variieren.

6voto

ulmer-morozov Punkte 1237

Ich habe mich bei meiner Antwort auf den Code von brmore gestützt;

Diese Funktion kann Inhalte in jedem Handler sicher lesen

private string SafeReadContentFrom(HttpRequestMessage request)
{
     var contentType = request.Content.Headers.ContentType;
     var contentInString = request.Content.ReadAsStringAsync().Result;
     request.Content = new StringContent(contentInString);
     request.Content.Headers.ContentType = contentType;
     return contentInString;
}

2voto

Barbaros Alp Punkte 6283

Das funktioniert bei mir.

[HttpPost]
public IHttpActionResult Index(HttpRequestMessage request)
{
    var form = request.Content.ReadAsFormDataAsync().Result;
    return Ok();
}

0voto

Sando Punkte 667

Ich hatte das gleiche Problem und entschied mich schließlich dafür, keine Inhalte in die Protokolle zu schreiben. Ich lebe mit der Protokollierung von Content-Type und Content-Length.

Aber es ist immer eine gute Idee, den gesamten Inhalt so weit wie möglich in die Protokolle zu schreiben.

Aber mit WebApi scheint dies derzeit nicht möglich zu sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X