RestSharp v112 响应处理指南:RestResponse 与 RestResponse\<T\> 属性全解析
2026/9/24 13:36:59 网站建设 项目流程

RestSharp v112 响应处理指南:RestResponse 与 RestResponse<T> 属性全解析

【免费下载链接】RestSharpSimple REST and HTTP API Client for .NET项目地址: https://gitcode.com/gh_mirrors/re/RestSharp

本指南以 RestSharp v112 版本文档的 "Handling responses" 一章为核心,系统讲解RestResponseRestResponse<T>的每一个公开属性、ResponseStatus状态机的语义,以及IsSuccessful的正确判定逻辑。读完本文,你将能熟练读取响应头、正文与错误信息,正确区分 HTTP 错误与传输层错误,并在实际项目中使用泛型响应安全地获取反序列化结果。

一、响应对象的两种形态:RestResponse 与 RestResponse<T>

在 RestSharp 中,所有Execute{Method}Async函数都会返回RestResponse实例;而以Execute{Method}Async<T>命名的泛型重载则返回RestResponse<T>,其中T是响应对象(反序列化目标)的类型。这一点在 execute.md 中列举的调用签名中可以看到:

Task<RestResponse> ExecuteGetAsync(RestRequest request, CancellationToken cancellationToken) Task<RestResponse<T>> ExecuteGetAsync<T>(RestRequest request, CancellationToken cancellationToken)

从源码看,两个类型是继承关系:RestResponse.cs 中定义了RestResponse<T>,它直接继承自RestResponse,并额外增加了一个Data属性;而 RestResponseBase.cs 中的RestResponseBase则承载了两个响应类型共享的全部公共属性。也就是说,无论你是否使用泛型重载,你拿到的响应对象都包含下面这套完整的属性。

二、RestResponse 完整属性表

RestResponse对象包含以下属性(内容直接继承自 response.md 官方文档):

属性类型说明
RequestRestRequest用于产生该响应的请求实例。
ContentTypestring?响应内容类型(MIME)。响应无内容时为Null
ContentLengthlong?响应内容长度(字节)。响应无内容时为Null
ContentEncodingICollection<string>内容编码集合。响应无内容时为空集合。
Contentstring?以字符串表示的响应内容。响应无内容时为Null
IsSuccessfulStatusCodebool指示响应是否成功,即服务器未报告错误。
ResponseStatusNoneCompletedErrorTimedOutAborted响应完成状态。注意:状态为Completed的响应仍然可能携带 HTTP 错误。
IsSuccessfulboolIsSuccessfulStatusCodetrueResponseStatusCompleted时为True
StatusDescriptionstring?响应状态描述(若可用)。
RawBytesbyte[]?以字节数组表示的响应内容。响应无内容时为Null
ResponseUriUri?响应对应的 URI,发生重定向时可能与请求 URI 不同。
Serverstring?响应的Server头值。
CookiesCookieCollection?响应携带的 Cookie 集合(若有)。
HeadersHeaderParameter集合响应头。
ContentHeadersHeaderParameter集合响应内容头。
ErrorMessagestring?尝试请求时产生的传输层或其他非 HTTP 错误。
ErrorExceptionException?执行请求时抛出的异常(若有)。
VersionVersion?请求的 HTTP 协议版本。
RootElementstring?序列化响应内容的根元素,仅在反序列化器支持时生效。

属性之间的细微差别

  • ContentRawBytesContent是经过解码的字符串形式,RawBytes是原始字节。需要保存文件、计算哈希或做二进制处理时优先使用RawBytes
  • HeadersContentHeaders:前者来自HttpResponseMessage.Headers(如ServerLocation),后者来自HttpResponseMessage.Content.Headers(如Content-TypeContent-Length)。二者在 RestResponse.cs 的FromHttpResponse中分别通过GetHeaderParameters()填充。
  • ResponseUri:从源码可见其特殊逻辑——当状态码位于 300~399 且存在Location头时,会优先解析重定向后的 URI(相对地址会基于请求 URI 组合),见 RestResponse.cs。

三、ResponseStatus:五种完成状态

ResponseStatus枚举定义于 Enum.cs,五种取值的精确语义如下:

取值语义
None不适用,通常表示请求尚未发出(构造RestResponseBase时的默认值,见 RestResponseBase.cs)。
Completed请求正常完成——HttpResponseMessage.IsSuccessStatusCodetrue,或响应状态为404 Not Found
Error请求失败——IsSuccessStatusCodefalse(404 除外)。
TimedOut请求超时——超过RestRequest.Timeout规定的时间或HttpClient自身超时导致操作取消。
Aborted操作被取消,且原因不是超时。

需要特别注意文档中的警告:Completed并不等于业务成功。服务器返回500之类的错误码时,网络传输本身是"完成"的,此时ResponseStatus仍可能是Completed,但IsSuccessfulStatusCodefalse。因此判断一次请求是否真正成功,请使用下一节的IsSuccessful,而不是单独看ResponseStatus

一个快速判断的成功属性:IsSuccessful

IsSuccessful的定义在 RestResponseBase.cs:

public bool IsSuccessful => IsSuccessStatusCode && ResponseStatus == ResponseStatus.Completed;

它要求两个条件同时成立:

  1. HTTP 状态码位于成功区间(IsSuccessStatusCode == true);
  2. 没有发生传输层错误、超时或取消(ResponseStatus == Completed)。

换句话说,IsSuccessful是"服务器层面成功"与"传输层面成功"的合取。在编写业务代码时,用if (response.IsSuccessful)作为总入口,可以同时覆盖 HTTP 错误与网络异常两类失败场景。

四、RestResponse<T> 的额外属性:Data

RestResponse<T>在继承全部上述属性的基础上,额外增加一个属性:

属性类型说明
DataT?反序列化后的响应对象。当响应无内容、反序列化器无法理解响应内容,或请求失败时,该属性为Null

DataExecuteAsync<T>系列泛型重载在获得响应后调用客户端配置的反序列化器填充,其声明位于 RestResponse.cs:

public partial class RestResponse<T>(RestRequest request) : RestResponse(request) { public T? Data { get; set; } }

典型用法:

var response = await client.ExecuteGetAsync<TResponse>(request, cancellationToken); if (response.IsSuccessful && response.Data is not null) { // 使用 response.Data 中的业务数据 } else { // 从 response.ErrorMessage / response.StatusCode 中提取失败原因 }

需要注意,DataNull有三种可能:响应体为空、反序列化失败、请求本身失败。所以即便IsSuccessful为真,也应防御性地对Data判空。

五、从源码看响应对象的构建过程

要真正理解这些属性的来源,可以阅读 RestResponse.cs 中的FromHttpResponse方法。RestSharp 在收到HttpResponseMessage后按以下步骤组装RestResponse

  1. 读取响应流并转为字节数组(stream.ReadAsBytes);
  2. 将字节按客户端配置的编码(options.Encoding)转为字符串,填充Content
  3. 逐项填充ContentTypeContentLengthContentEncodingContentHeadersHeadersServerStatusCodeStatusDescriptionResponseStatusVersion等;
  4. 将 HTTP 响应头的Location等用于计算ResponseUri
  5. request.RootElement透传到RootElement,供支持根元素的反序列化器使用;
  6. 依据options.SetErrorExceptionOnUnsuccessfulStatusCode决定是否在非成功状态码时填充ErrorException

这条构建路径解释了为什么ContentContentTypeContentLength在"响应无内容"时会为Null——它们都来源于HttpResponseMessage.Content,而Content本身为空时这些属性自然无从谈起。

六、配套扩展方法:读取头与抛出错误

除了属性,RestSharp 还提供了与响应对象配套的扩展方法:

读取响应头

RestResponseExtensions.cs 提供了按名称读取头的方法(大小写不敏感匹配):

// 单个值 string? etag = response.GetHeaderValue("ETag"); // 多个值(同名头出现多次时) string[] values = response.GetHeaderValues("Set-Cookie"); // 内容头同理 string? contentType = response.GetContentHeaderValue("Content-Type"); string[] contentHeaders = response.GetContentHeaderValues("Content-Encoding");

抛出错误异常

ResponseThrowExtension.cs 提供了ThrowIfError(),它会根据ResponseStatus生成对应异常并抛出:

  • AbortedHttpRequestException("Request aborted", ErrorException)
  • Error→ 返回原始ErrorException
  • TimedOutTimeoutException("Request timed out", ErrorException)

该映射逻辑见 RestResponseBase.cs 的GetException()方法:

var response = await client.ExecuteAsync(request, cancellationToken); var checked = response.ThrowIfError(); // 失败时抛出,成功时原样返回

这在"希望把异常处理交给调用方"的中间层代码中非常实用。

七、错误场景的判定要点与测试佐证

文档强调:Execute前缀的调用在服务器返回错误时不会抛异常,而是把错误信息放进响应对象,方便调用方检查(参见 execute.md 的 "Beware of errors" 提示)。因此,判断失败需要组合多个信号:

  1. 传输层/取消问题:看ResponseStatus是否为TimedOutAbortedError,以及ErrorMessage/ErrorException是否有值;
  2. HTTP 层问题:看IsSuccessfulStatusCodeStatusCode/StatusDescription
  3. 反序列化问题:泛型响应中Data == null

仓库中的测试也印证了这一模型,例如 ErrorMessageTests.cs 中直接断言response.ResponseStatus.Should().Be(ResponseStatus.Error),验证了传输错误会反映到ResponseStatus上。GetException()的实现也说明:只有在ResponseStatus明确为错误状态时才产生异常,这也是ThrowIfError只在真正失败时抛出的原因。

八、小结

  • 非泛型Execute{Method}Async返回RestResponse,泛型版本返回RestResponse<T>(额外带Data);
  • IsSuccessful是"HTTP 成功 + 传输完成"的双重判定,是业务代码的首选判断入口;
  • ResponseStatusCompleted不代表业务成功,必须结合IsSuccessfulStatusCode一起看;
  • 响应头、Cookie、原始字节、错误信息分别对应Headers/ContentHeadersCookiesRawBytesErrorMessage/ErrorException属性;
  • 需要把错误转为异常时,可以使用ThrowIfError()扩展方法。

建议进一步阅读 execute.md(如何发起请求)、error-handling.md(错误处理策略)以及 serialization.md(Data反序列化机制),配合 RestResponse.cs 与 RestResponseBase.cs 的源码,即可完整掌握 RestSharp 的响应处理链路。

【免费下载链接】RestSharpSimple REST and HTTP API Client for .NET项目地址: https://gitcode.com/gh_mirrors/re/RestSharp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询