2016-03-01 20 views
6

Sto cercando di implementare questo code example, ma ottenere un errore HttpRequestException - "durante la copia di contenuto in uno streaming". quando viene chiamato il metodo ReadAsStringAsync(). L'eccezione interna è "Impossibile accedere a un oggetto disposto". Sto usando Fiddler per fare la richiesta. Non capisco. Qualcuno può spiegare perché sto ricevendo questa eccezione e offro una soluzione?Richiesta Web Api genera "Errore durante la copia del contenuto in un flusso".

Web metodo API:

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

Fiddler (POST):

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

Edit:

ho un indizio, ma bisogno di verifica. Sul controller Api Web, ho un ActionFilterAttribute e nella sua OnActionExecuting override, c'è questa linea:

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

Potrebbe essere che perché il contenuto viene letto qui, non è ancora disponibile? In tal caso, come posso renderlo disponibile nel metodo? Il contenuto è lo stesso di HttpRequestMessage? This potrebbe contenere una risposta.

+0

Come stai chiamando questo metodo? –

+0

@YuvalItzchakov ... Sto usando Fiddler –

+0

Questo metodo è un'azione API Web? –

risposta

1

A causa del ActionFilterAttribute's controllore Il metodo OnActionExecuting chiama ReadAsStreamAsync, il contenuto non può essere letto di nuovo. Ho modificato ReadAsStreamAsync in ReadAsStringAsync e il contenuto della richiesta è disponibile nel controller. Apparentemente, ReadAsStringAsync memorizza il contenuto in modo che sia ancora disponibile. Questo link ha fornito la risposta.

1

solo un ospite, dovrebbe inviare come commento ma voglio includere un codice di SIPNET:

Forse si chiamano Post funzione all'interno di un blocco using, ma non usare await.

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

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

Oppure non disporre i vecchi collegamenti correttamente.

Inoltre, cercare aggiungi HttpVersion.Version10 alla vostra richiesta, che cambiano richiesta colpo di testa da Connection: keep-alive a Connection: close, che può causare un'eccezione in alcuni casi si riutilizza un host (Ricerca per ulteriori informazioni)

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

Grazie, senza fortuna con questi –

1

Spero che questo (in ritardo) post vi aiuterà qualcuno un giorno ...

In breve: la risposta accettata suggerisce di leggere l'intero file come stringa (e non come stream) al fine di aggirare un problema di lettura

MA ...lettura di un file come una stringa non è una grande idea

ho capito che la sostituzione MultipartFormDataStreamProvider con MultipartMemoryStreamProvider funziona alla grande - e permettono di leggere il file caricato, se lo desideri

Il mio codice (almeno il parti rilevanti di esso)

[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); 
     } 
    } 
Problemi correlati