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

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

问题描述

大家好,我正在尝试使用 RestSharp 登录我的 xamarin api,如果身份验证有效,API 应该返回状态代码 200 OK,如果身份验证失败(密码错误)和其他代码,则取决于什么,返回状态代码 415案例场景,但是当身份验证通过(状态代码 200 ok)时,我在所有其他案例中得到状态代码 0,下面的源代码是我如何实现

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 值不能为空.参数名称: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 调用并调用您给它的函数.问题是,这被定义为一个 Action 而你没有得到完整响应对象的副本,所以它有点没用.相反,您必须使用 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 值不能为空.参数名称:src"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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