首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RestSharp“错误获取响应流(ReadAsync):ReceiveFailure值不能为空。参数名称: src”

RestSharp“错误获取响应流(ReadAsync):ReceiveFailure值不能为空。参数名称: src”
EN

Stack Overflow用户
提问于 2018-09-19 09:31:38
回答 2查看 4.8K关注 0票数 3

大家好,我正试图使用RestSharp登录我的xamarin api,如果身份验证有效,应该返回状态代码200 OK,如果身份验证失败(密码错误)则返回状态代码415,以及其他代码(取决于具体情况),但是当身份验证通过(状态代码200 ok)时,我将在所有其他情况下获得状态代码0,下面的源代码是我如何实现的。

代码语言:javascript
复制
 //payload am sending to the api
   RequestPayload res = new RequestPayload();
   res.appid = appid;
   res.data = data;
   res.method = "Login";

   //convert to json object
   var MySerializedObject =  JsonConvert.SerializeObject(res);
   string APIUrl = ""http://142.168.20.15:8021/RouteTask";

   //create client
   RestClient client = new RestClient(APIUrl);

   //create request
   RestRequest request = new RestRequest(Method.POST);

   // set request headeer
   request.AddHeader("Content-Type", "application/x-www-form-urlencoded");

   //request.AddJsonBody(MySerializedObject); --i have also tried this

   request.AddParameter("application/json", MySerializedObject, ParameterType.RequestBody);
   request.JsonSerializer.ContentType = "application/json; charset=utf-8";
   request.AddParameter("RequestSource", "Web", "application/json", ParameterType.QueryString);
   client.Timeout = 2000000;
   var response =  client.Execute(request); // where the issue appears
   //RestResponse response =  client.Execute(request); // i have tried this
   //IRestResponse response =  client.Execute(request); // i have tried this
    if (response.IsSuccessful)
        {
         //use response data
        }

在所有场景中,它返回一个StatusCode: 0、Content:、Content: 0)和errorMessage

获取响应流(ReadAsync)错误: ReceiveFailure值不能为空。参数名称:src

下面的屏幕截图显示api调用何时失败

在身份验证有效时接收响应

EN

回答 2

Stack Overflow用户

发布于 2018-09-27 16:44:23

我终于找到了解决办法。忍受长篇大论的回应。

标签中提到了Xamarin,这也是我正在从事的工作--特别是使用iOS。我认为这可能是Mono的一个bug,但我并没有去证实。

问题在于复制响应缓冲区的默认方法。在RestSharp代码中,这是由MiscExtensions.cs中的一个名为ReadAsBytes的扩展方法完成的。对于某些响应缓冲区,对Stream.Read方法的调用似乎失败。当这种情况发生时,异常会导致RestSharp“快捷”响应上的其余处理,因此状态代码不会被填充,因为它发生在对ReadAsBytes的调用之后。

好消息是,RestSharp确实给出了一种用自己的调用替换对ReadAsBytes的调用的方法。这是通过ResponseWriter属性在IRestRequest对象上完成的。如果它定义了一个函数,它将绕过ReadAsBytes调用,转而调用您给它的函数。问题是,这被定义为一个Action,并且您没有得到完整响应对象的副本,所以它有点无用。相反,您必须使用AdvancedResponseWriter属性。这个包括响应对象和响应流。但是您仍然必须设置ResponseWriter属性,否则它不会绕过默认处理程序,并且仍然会得到错误。

好吧,那你是怎么做到的呢?最后,我将它作为RestClient的包装器实现,这样我就不必在各地实现代码了。以下是基本设置:

代码语言:javascript
复制
public class MyRestClient : RestClient
{
    public MyRestClient(string baseUrl) : base(baseUrl)
    { }

    public override IRestResponse Execute(IRestRequest request)
    {
        request.ResponseWriter = s => { };
        request.AdvancedResponseWriter = (input, response) => response.RawBytes = ReadAsBytes(input);

        return base.Execute(request);
    }

    private static byte[] ReadAsBytes(Stream input)
    {
        var buffer = new byte[16 * 1024];

        using (var ms = new MemoryStream())
        {
            int read;
            try
            {
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                { ms.Write(buffer, 0, read); }

                return ms.ToArray();
            }
            catch (WebException ex)
            { return Encoding.UTF8.GetBytes(ex.Message); }
        };
    }
}

ReadAsBytes方法实际上只是RestSharp ReadAsBytes方法的复制/粘贴,并添加了try/catch。如果失败,则将异常原因返回到响应缓冲区。这可能是您想要的,也可能不是您想要的,所以请根据需要进行修改。您可能还需要重写执行的其他方法,但在我的例子中,这是我们使用的唯一方法,所以这就足够了。

到目前为止,这似乎对我有好处。也许如果有人雄心勃勃,他们可以一路追踪到Mono,看看它对溪流有什么不喜欢的地方,但我现在没有时间去做。

祝好运!

票数 4
EN

Stack Overflow用户

发布于 2018-10-06 10:01:53

好的,在玩了一会儿RestSharp之后,我意识到正如@steve_In_Co前面提到的,MONO (我们假设这是一个bug)存在兼容性问题,所以我使用.Net HTTP库以一种基本的方式完成了它,所以如果有人还在寻找出路,请在下面找到正在工作的.net http实现代码。

代码语言:javascript
复制
//payload am sending to the api 
   RequestPayload res = new RequestPayload();
   res.appid = appid;
   res.data = data;
   res.method = "Login";

   //convert to json object
   var MySerializedObject =  JsonConvert.SerializeObject(res);

   string APIUrl = ""http://142.168.20.15:8021/RouteTask";

   //create basic .net http client
   HttpClient client = new HttpClient();
   client.BaseAddress = new Uri(APIUrl);

   // this was required in the header of my request, 
   // you may not need this, or you may need to adjust parameter
   //("RequestSource","Web") or you own custom headers
   client.DefaultRequestHeaders.Add("RequestSource", "Web");
    // this class is custom, you can leave it out
   connectionService = new ConnectionService();
  //check for internet connection on users device before making the call
  if (connectionService.IsConnected)
    {
       //make the call to the api
        HttpResponseMessage response = await 
        client.PostAsJsonAsync(ApiConstants.APIDefault, res);
        if (response.IsSuccessStatusCode)
            {
                string o = response.Content.ReadAsStringAsync().Result;
                dynamic payload = JsonConvert.DeserializeObject(o);
                string msg = payload["valMessage"];
                resp.a = true;
                resp.msg = payload["responseDescription"];
            }
        else
            {
                string o = response.Content.ReadAsStringAsync().Result;
                dynamic payload = JsonConvert.DeserializeObject(o);
                resp.a = false;
                resp.msg = payload["response"];
            }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52402634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档