RestSharp"获取响应流(ReadAsync)时出错:ReceiveFailure值不能为null.参数名称:"src". [英] RestSharp "Error getting response stream (ReadAsync): ReceiveFailure Value cannot be null. Parameter name: src"

查看:190
本文介绍了RestSharp"获取响应流(ReadAsync)时出错:ReceiveFailure值不能为null.参数名称:"src".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家都在尝试使用RestSharp登录我的xamarin api,如果身份验证有效,则API应该返回状态代码200 OK,如果身份验证失败(错误密码),则API返回状态代码415,而其他代码则取决于情况下,但是在身份验证通过时,我在所有其他情况下得到的状态代码为0(状态代码为200 ok),下面的源代码是我的实现方式

Hello all am trying to do a login to my xamarin api using RestSharp, the API ought to return status code 200 OK if the authentication works and status code 415 if the authentication fails(wrong password) and other codes depending on what the case scenario, but instead i get a status code 0 on all other case asides when the authentication pass(status code 200 ok), the source code below is how i implement

 //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-Type:,Content-Length:0)和errorMessage

on all scenerio it comes back with a StatusCode: 0, Content-Type: , Content-Length: 0) and errorMessage

获取响应流(ReadAsync)时出错:ReceiveFailure值 不能为null.参数名称:src"

"Error getting response stream (ReadAsync): ReceiveFailure Value cannot be null. Parameter name: src"

下面的

屏幕截图指示api调用何时失败 验证有效时收到响应

screenshot below indicate when the api call fails Response receieved when the authentication is valid

推荐答案

我终于能够找到解决此问题的方法.忍受漫长的反应.

I was finally able to find a workaround for this. Bear with the long-winded response.

标签提到Xamarin,这也是我正在使用的-特别是在iOS中.我认为这实际上可能是Mono的一个错误,但我并没有做那么多的确认.

The tags mention Xamarin, which is what I am working in as well - specifically with iOS. I think it may actually be a bug with Mono, but I didn't take it that far to confirm.

问题在于复制响应缓冲区的默认方式.在RestSharp代码中,这是通过MiscExtensions.cs中称为ReadAsBytes的扩展方法完成的.似乎对于某些响应缓冲区,对Stream.Read方法的调用失败.发生这种情况时,异常会导致RestSharp缩短响应中其余的处理,因此状态代码永远不会被填充,因为它发生在调用ReadAsBytes之后.

The problem lies with the default way of copying the response buffer. In the RestSharp code, this is done by an extension method in MiscExtensions.cs called ReadAsBytes. It appears that with certain response buffers, the call to the Stream.Read method is failing. When this happens, the exception causes RestSharp to "shortcut" the rest of the processing on the response, hence the status code never gets filled in since it happens after the call to ReadAsBytes.

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

The good news is RestSharp does give a way to replace this call to ReadAsBytes with one of your own. This is done via the ResponseWriter property on the IRestRequest object. If it has a function defined, it will bypass the ReadAsBytes call and call the function you gave it instead. The problem is, this is defined as an Action and you don't get a copy of the full response object, so it's somewhat useless. Instead you have to use the AdvancedResponseWriter property. This one includes both the response object and the response stream. But you still have to set the ResponseWriter property or it won't bypass the default handler and you'll still get the error.

好的,那么您如何进行这项工作?我最终将其实现为RestClient的包装,因此不必在所有位置实现代码.这是基本设置:

Ok, so how do you make this work? I ended up implementing it as a wrapper to RestClient so I wouldn't have to implement the code all over the place. Here's the basic setup:

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.如果失败,则将异常原因返回到响应缓冲区.这可能是您想要的,也可能不是您想要的,因此请根据需要进行修改.您可能还需要重写Execute的其他方法,但就我而言,这是我们正在使用的唯一方法,因此就足够了.

The ReadAsBytes method is actually just a copy/paste of the RestSharp ReadAsBytes method with the addition of a try/catch. If it fails, it returns the exception reason in to the response buffer. This may or may not be what you want, so modify as needed. You may also need to override other methods for Execute, but in my case this is the only one we're using so it was enough.

到目前为止,这似乎对我有用.也许如果某人雄心勃勃,他们可以一直追踪到Mono,尝试查看对流不满意的地方,但是我现在没有时间.

So far this seems to be doing the trick for me. Perhaps if someone got ambitious they could trace it all the way in to Mono to try and see what it doesn't like about the stream, but I don't have the time for it at the moment.

祝你好运!

这篇关于RestSharp"获取响应流(ReadAsync)时出错:ReceiveFailure值不能为null.参数名称:"src".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆