检查响应状态后将 RestSharp 响应作为流处理?

Process RestSharp Response as a Stream after checking the response status?

我必须能够使用 RestSharp 从我们的 Rest API 流式传输大文件。这样做的规范方法是根据请求设置 'ResponseWriter' 属性:

var client = new RestClient
var request = new RestRequest();
IRestResponse response;
request.ResponseWriter = connectStream => {
  if(response.StatusCode == ResponseStatus.OK)
  {
     CloudStorage.UploadFromStream(connectStream);
  }
  else
  {
     LoggerService.LogErrorFromStream(connectStream);
  }
};
response = client.Execute(request);

我的问题是 'response' object(包括状态、状态代码、headers 等)在 [=20 之后才可用=] RestSharp 已完成要求我的 ResponseWriter 处理整个流。

这似乎 counter-intuitive,因为用户当然可能希望根据响应状态更改响应流的处理方式。

如何在开始处理响应流之前获取此状态信息body?

看起来有些 headers 是在调用 ResponseWriter 之前设置的,这发生在 ProcessResponseStream 方法内部,有些 headers 是在调用 ResponseWriter 之前设置的。 Status 是调用 ResponseWriter 后设置的 headers 之一。

见代码:RestSharp Http.cs

       private void ExtractResponseData(HttpResponse response, HttpWebResponse webResponse)
        {
            using (webResponse)
            {
#if FRAMEWORK
                response.ContentEncoding = webResponse.ContentEncoding;
                response.Server = webResponse.Server;
                response.ProtocolVersion = webResponse.ProtocolVersion;
#endif
                response.ContentType = webResponse.ContentType;
                response.ContentLength = webResponse.ContentLength;

                Stream webResponseStream = webResponse.GetResponseStream();

#if WINDOWS_PHONE
                if (string.Equals(webResponse.Headers[HttpRequestHeader.ContentEncoding], "gzip", StringComparison.OrdinalIgnoreCase))
                {
                    GZipStream gzStream = new GZipStream(webResponseStream);

                    ProcessResponseStream(gzStream, response);
                }
                else
                {
                    ProcessResponseStream(webResponseStream, response);
                }
#else
                this.ProcessResponseStream(webResponseStream, response);
#endif

                response.StatusCode = webResponse.StatusCode;
                response.StatusDescription = webResponse.StatusDescription;
                response.ResponseUri = webResponse.ResponseUri;
                response.ResponseStatus = ResponseStatus.Completed;

我想这已经在 here 之前报道过了。

看起来他们 released 对此进行了更新,方法是改用 AdvancedResponseWriter

var client = new RestClient
var request = new RestRequest();
IRestResponse response;
request.AdvancedResponseWriter = (stream, response) => {
    // Should be able to access response which is an IHttpResponse
};
response = client.Execute(request);

Docs.