2014-05-08 4 views
5

Non riesco a percepire alcune eccezioni generate dal metodo SendAsync System.Net.Http.HttpClient. In particolare, ProtocolViolationException, generata dal metodo HttpWebRequest.ChechProtocol. Il codice sembra bloccarsi o bloccarsi e il problema non viene mai inserito.Perché non riesco ad ottenere l'eccezione da HttpClient SendAsync quando utilizzo ObjectContent

Ho creato un test dell'unità NUnit per illustrare chiaramente il problema.

public class TestClass 
{ 
    public bool TestProperty { get; set; } 
} 

[Test] 
public async Task CanCatchExceptionFromHttpClientSendAsync() 
{ 
    var caughtException = false; 

    try 
    { 
     var request = new HttpRequestMessage(HttpMethod.Get, "http://somedomain.com") 
     { 
      Content = new ObjectContent<TestClass>(
       new TestClass { TestProperty = true }, 
       new JsonMediaTypeFormatter()) 
     }; 

     await new HttpClient().SendAsync(request); 
    } 
    catch (Exception) 
    { 
     caughtException = true; 
    } 

    Assert.IsTrue(caughtException); 
} 

utilizzando StringContent anziché ObjectContent passa il test. Mi sto perdendo qualcosa di semplice?

Aggiornamento

Sulla base del fatto che StringContent permette l'eccezione di essere catturati, e deadlock ObjectContent, sono stato in grado di dedurre che questo è in qualche modo legato al metodo di WriteToStreamAsync del MediaTypeFormatter.

sono riuscito a risolvere il problema "pre-formattazione" il contenuto in un ByteArrayContent in questo modo:

private static async Task<HttpContent> CreateContent<T>(
    T value, 
    string mediaType, 
    MediaTypeFormatter formatter) 
{ 
    var type = typeof(T); 
    var header = new MediaTypeHeaderValue(mediaType); 

    HttpContent content; 
    using (var stream = new MemoryStream()) 
    { 
     await formatter.WriteToStreamAsync(type, value, stream, null, null); 

     content = new ByteArrayContent(stream.ToArray()); 
    } 

    formatter.SetDefaultContentHeaders(type, content.Headers, header); 

    return content; 
} 

e poi consumare in questo modo:

var content = await CreateContent(
    new TestClass(), 
    "application/json", 
    new JsonMediaTypeFormatter()); 

var request = new HttpRequestMessage(HttpMethod.Get, "http://foo.com") 
{ 
    Content = content 
}; 

Quello almeno consente al blocco di funzionare correttamente, ma I

+0

Prova a utilizzare HttpMethod.Post – ad1Dima

+0

Ciò impedisce l'esecuzione dell'eccezione, certo. Ma non risolve il problema di non essere in grado di cogliere l'eccezione. –

risposta

1

Questo è un bug noto in HttpClient. È possibile risolvere il problema effettuando il buffering, impostando la lunghezza del contenuto (come fa ByteArrayContent) o utilizzando la codifica di trasferimento Chunked (se supportato sulla propria piattaforma, non supportato sul telefono).

+0

Questo è quello che sospettavo. C'è un problema di connessione o qualcosa che può essere votato? –

Problemi correlati