2016-03-01 18 views
6

Próbuję zaimplementować to code example, ale otrzymam błąd HttpRequestException - "podczas kopiowania treści do strumienia." po wywołaniu metody ReadAsStringAsync(). Wewnętrzny wyjątek to "Nie można uzyskać dostępu do usuniętego obiektu." Używam Skrzypka do złożenia wniosku. Nie rozumiem. Czy ktoś może wyjaśnić, dlaczego otrzymuję ten wyjątek i oferuje rozwiązanie?Żądanie Web Api zgłasza "Błąd podczas kopiowania treści do strumienia".

Web metoda API:

public async Task<HttpResponseMessage> Post(HttpRequestMessage request) 
{ 
    try 
    { 
     var jsonString = await request.Content.ReadAsStringAsync(); 
    } 
    catch (Exception ex) 
    {     
     throw; 
    } 
    return new HttpResponseMessage(HttpStatusCode.Created); 
} 

Skrzypek (POST):

User-Agent: Fiddler 
Host: localhost:23567 
Content-Length: 18 
Content-Type: application/json; charset=utf-8 
Body{"Test":1} 

Edit:

mam pojęcia, ale wymagają weryfikacji. Na kontrolerze Api Web, mam ActionFilterAttribute iw jego OnActionExecuting ręcznym, jest to linia:

public override async void OnActionExecuting(HttpActionContext actionContext) 
{ 
    // omitted code 
    actionContext.Request.Content.ReadAsStreamAsync(); 
} 

Czyżby dlatego, że zawartość jest tu czytać, to nie jest dostępny? Jeśli tak, jak mogę udostępnić tę metodę? Czy zawartość jest tutaj taka sama jak HttpRequestMessage? This może zawierać odpowiedź.

+0

Jak nazwać tę metodę? –

+0

@YuvalItzchakov ... Używam Fiddlera –

+0

Czy ta metoda jest działaniem Web API? –

Odpowiedz

1

Ponieważ kontrolera ActionFilterAttribute'sOnActionExecuting Metoda nazywa się ReadAsStreamAsync, treść nie może zostać ponownie odczytana. Zmieniłem ReadAsStreamAsync na ReadAsStringAsync, a treść żądania dostępna jest w kontrolerze. Odtąd ReadAsStringAsync buforuje zawartość, dzięki czemu jest nadal dostępna. Ten link dostarczył odpowiedź.

1

tylko gościem, należy dodawać jako komentarz, ale chcę obejmują sipnet kodu:

Może zadzwonić Post funkcji wewnątrz using bloku, ale nie używaj await.

using (HttpRequestMessage request = ...) 
{ 
    // Maybe you use this: 
    Post(request); 

    // Instead of this 
    var response = await Post(request); 
} 

Lub nie wyrzucaj starych połączeń prawidłowo.

Spróbuj też dodać HttpVersion.Version10 na żądanie, które zmieniają wniosek Główka Connection: keep-alive do Connection: close, co może spowodować wyjątek w pewnym przypadku ponownego użycia hosta (Search aby uzyskać więcej informacji)

request.Version = HttpVersion.Version10; 
var jsonString = await request.Content.ReadAsStringAsync(); 
+0

Dzięki, nie ma szczęścia z tymi –

1

Mam nadzieję, że ten (późno) po pomoże ktoś kiedyś ...

W skrócie: zaakceptowane odpowiedź sugeruje, aby przeczytać cały plik jako ciąg (a nie jako strumień) w celu ominięcia problemu odczytu

ALE ...odczyt z pliku jako ciąg nie jest taki świetny pomysł

zorientowali się, że zastąpienie MultipartFormDataStreamProvider z MultipartMemoryStreamProvider działa świetnie - i pozwala odczytać przesłanego pliku zgodnie z potrzebami

mojego kodu (przynajmniej odpowiednie części)

[HttpPost] 
    [Route("upload/file")] // you may replace this route to suit your api service 
    public async Task<IHttpActionResult> Upload() 
    { 
     if (!Request.Content.IsMimeMultipartContent("form-data")) 
     { 
      return BadRequest("Unsupported media type"); 
     } 

     try 
     { 
      var provider = new MultipartMemoryStreamProvider(); 

      await Request.Content.ReadAsMultipartAsync(provider); 

      if (provider.Contents.Count == 0) return InternalServerError(new Exception("Upload failed")); 

      var file = provider.Contents[0]; // if you handle more then 1 file you can loop provider.Contents 

      var buffer = await file.ReadAsByteArrayAsync(); 

      // .. do whatever needed here 

      return Ok(); 

     } 
     catch (Exception ex) 
     { 
      return BadRequest(ex.GetBaseException().Message); 
     } 
    } 
Powiązane problemy