C# HttpRequestException与WebException

C# HttpRequestException与WebException,c#,rest,dotnet-httpclient,webexception,C#,Rest,Dotnet Httpclient,Webexception,这是一个我感到困惑的普遍问题。我认为一旦发出REST请求,就会通过WebException返回错误。在一个例子中,我得到了一个HttpRequestException,它不允许我获得HTTP状态码 我对这些东西不熟悉,但它们之间有什么区别?为什么有两种类型?什么时候一个习惯于另一个 WebException似乎运行良好HttpRequestException似乎是它的一个非常弱的版本,它知道状态代码(在它的消息中),但它不会明确告诉我它是什么 编辑: 我正在使用一个HttpClient。特别是调

这是一个我感到困惑的普遍问题。我认为一旦发出REST请求,就会通过
WebException
返回错误。在一个例子中,我得到了一个
HttpRequestException
,它不允许我获得HTTP状态码

我对这些东西不熟悉,但它们之间有什么区别?为什么有两种类型?什么时候一个习惯于另一个

WebException
似乎运行良好
HttpRequestException
似乎是它的一个非常弱的版本,它知道状态代码(在它的消息中),但它不会明确告诉我它是什么

编辑: 我正在使用一个
HttpClient
。特别是调用
client.GetStreamAsync()
:通过可插拔协议访问网络时发生错误时引发的异常

:HttpClient和HttpMessageHandler类引发的异常的基类

我认为HttpRequestException的内部异常可能是WebException,但我不确定它是否是



注意,404、302或除200(正常)以外的任何响应都不是异常。这些响应是完全有效的HTTP响应。

有三种不同的故障场景:

a) 您无法连接到服务器或代理,在这种情况下会引发HttpRequestException。请注意,如果您的服务器已关闭并且正在运行fiddler,您将永远不会看到此异常,您将获得5XX状态代码

b) 在读取/写入网络流时,会出现某种中断,您将获得IOException

c) 您将返回一个带有HttpStatusCode和4XX/5XX状态代码的响应。如果您的客户端应用程序选择调用response.EnsureSuccessStatusCode(),则会引发HttpRequestException

如果您决定调用EnsureSuccessStatusCode,则表明您不关心状态代码,而只关心它是成功/失败


如果您真的需要冒泡出一个异常,然后在以后处理状态代码,那么我建议您创建自己的扩展方法来替换EnsureAccessStatusCode,并创建自己的异常来存储状态代码。或者,最好根据您希望采取的纠正措施,将状态代码转换为几个不同的异常之一。

在.NET 5中将
StatusCode
添加到
HttpRequestException

您应该添加抛出的代码(这样人们就可以知道您是否在使用WebClient、HttpClient或其他类)抱歉,我正在使用HttpClient。专门调用client.GetStreamAsync()。但我更感兴趣的是了解它的工作原理,而不是试图解决特定的代码问题,所以我不想用太多的代码来混淆它。是的,HttpRequestException有时是一个WebException,它应该让您能够访问状态。我看到了MSDN定义,但这并不能真正解释它,或者我在这方面不够精明,无法理解它试图告诉我的细微差别。在我的情况下,HttpRequestException不是WebException,也不是任何InnerException。@PeterRitchie我认为WebException不应该出现在HttpClient中,除非作为HttpRequestException或IOException的内部异常。@Darreller在阅读我的评论时,我不清楚。。。这就是我想说的;该HttpRequestException有时会包装一个WebException,该WebException将提供对HttpStatusCode的访问。@PeterRitchie除非HttpRequestException是由EnsureAccessStatusCode引发的,在这种情况下不存在WebException,或者WebException与连接失败相关,在这种情况下,也没有状态代码。+1但您忘记了一件事,那就是超时异常(这会令人困惑地抛出TaskCanceledException:)@OhadSchneider是的,我忘记了。谢谢你提出来。