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
Prova a utilizzare HttpMethod.Post – ad1Dima
Ciò impedisce l'esecuzione dell'eccezione, certo. Ma non risolve il problema di non essere in grado di cogliere l'eccezione. –