gpt4 book ai didi

c# - 为什么在使用 ObjectContent 时无法从 HttpClient SendAsync 捕获异常

转载 作者:太空狗 更新时间:2023-10-29 21:57:48 27 4
gpt4 key购买 nike

我似乎无法捕获从 System.Net.Http.HttpClient 的 SendAsync 方法抛出的某些异常。具体来说,是从 HttpWebRequest.ChechProtocol 方法抛出的 ProtocolViolationException。代码似乎死锁或挂起,并且从未输入 catch。

我已经创建了一个 NUnit 单元测试来清楚地说明这个问题。

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);
}

使用 StringContent 而不是 ObjectContent 测试通过。我错过了一些简单的东西吗?

更新

基于 StringContent 允许捕获异常和 ObjectContent 死锁这一事实,我已经能够推断出这在某种程度上与 MediaTypeFormatter 的 WriteToStreamAsync 方法有关。

我已经设法通过将内容“预格式化”到 ByteArrayContent 来解决这个问题,如下所示:

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;
}

然后像这样消费它:

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

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

这至少可以让捕获正常工作,但我

最佳答案

这是 HttpClient 中的一个已知错误。您可以通过自己缓冲、设置内容长度(如 ByteArrayContent 所做的那样)或使用分块传输编码(如果您的平台支持,但手机不支持)来解决此问题。

关于c# - 为什么在使用 ObjectContent 时无法从 HttpClient SendAsync 捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23547814/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com