Xamarin NSURLSession获取请求:DidCompleteWithError-错误为null

Xamarin NSURLSession获取请求:DidCompleteWithError-错误为null,xamarin,xamarin.ios,nsurlsession,Xamarin,Xamarin.ios,Nsurlsession,目前,我正在尝试从不推荐的NSUrlConnection切换到NSUrlSession。 我试图实现的是通过GET请求调用IIS Web服务,然后处理XML应答。 我有两个问题: 如果答案太长,则DidReceiveData中的NSData对象不包含所有内容。答案在1036个字符后被裁剪 完成所有操作后,当im已经在处理接收到的数据时(无论数据是否被裁剪),就会调用DidCompleteWitheror。其中的“error”参数为null,所以我不知道为什么会调用它以及如何处理它。因此,即使我收

目前,我正在尝试从不推荐的NSUrlConnection切换到NSUrlSession。 我试图实现的是通过GET请求调用IIS Web服务,然后处理XML应答。 我有两个问题:

  • 如果答案太长,则DidReceiveData中的NSData对象不包含所有内容。答案在1036个字符后被裁剪
  • 完成所有操作后,当im已经在处理接收到的数据时(无论数据是否被裁剪),就会调用DidCompleteWitheror。其中的“error”参数为null,所以我不知道为什么会调用它以及如何处理它。因此,即使我收到了DidReceiveData中的所有数据,并且一切正常,DidCompleteWitheror也会被调用
  • 这是我的代码,非常感谢您的帮助。提前谢谢

    public class WebserviceCallerIOS : IWebServiceCaller
        {
            private NSMutableUrlRequest request;
            public NSUrlSessionDataTask dataTask;
            private Action<bool, string> completed;
            private string antwort;
            private NSUrlSession session;
            public NSOperationQueue myQueue;
    
            public void Invoke(string sUrl)
            {
                session = null;
                antwort = null;
                completed = null;
                myQueue = new NSOperationQueue();
    
                session = NSUrlSession.FromConfiguration(NSUrlSessionConfiguration.DefaultSessionConfiguration, (INSUrlSessionDelegate)new SessionDelegate((erfolg, body) => { completed(erfolg, body); }), myQueue);
                completed += WebserviceCallerIOS_Completed;
    
                try
                {
                    request = CreateNativePostRequest(sUrl);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    completed(false, "Error creating request: " + e);
                }
    
                dataTask = session.CreateDataTask(request);
                dataTask.Resume();
            }
    
            NSMutableUrlRequest CreateNativePostRequest(string url)
            {
                string converted = ((NSString)url).CreateStringByAddingPercentEscapes(NSStringEncoding.UTF8);
                var nsurl = NSUrl.FromString(converted);
    
                if (nsurl == null)
                    throw new Exception("Invalid URL, could not create NSUrl from: '" + url + "'.");
    
                var req = new NSMutableUrlRequest(nsurl) {HttpMethod = "GET"};
                return req;
            }
    
    private class SessionDelegate : NSUrlSessionDataDelegate, INSUrlSessionDelegate
            {
                private Action<bool, string> completed_callback;
                private NSData retData;
                private int status_code;
    
                public SessionDelegate(Action<bool, string> completed)
                {
                    completed_callback = completed;
                    retData = new NSData();
                }
    
    
                public override void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler)
                {
                    var http_response = response as NSHttpUrlResponse;
                    if (http_response == null)
                    {
                        Console.WriteLine("Received non HTTP url response: '{0}'", response);
                        status_code = -1;
                        return;
                    }
    
    
                    status_code = (int)http_response.StatusCode;
    
                    if (status_code == 200)
                {
                    completionHandler(NSUrlSessionResponseDisposition.Allow);
                }
                else 
                {
                    completionHandler(NSUrlSessionResponseDisposition.Cancel);
                }
            }
    
    
                public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error)
                {
                    completed_callback(false, error?.LocalizedDescription);
                }
    
    
                public override void DidReceiveData(NSUrlSession session, NSUrlSessionDataTask dataTask, NSData data)
                {
                    retData = data;
                    dataTask.Suspend();
                    Console.WriteLine(retData);
                    completed_callback(true, retData.ToString());
                }
        }
    }
    
    公共类WebserviceCallerIOS:IWebServiceCaller
    {
    私有NSMutableUrlRequest请求;
    公共NSUrlSessionDataTask数据任务;
    完成私人行动;
    私家串珠;
    非公开会议;
    公共NSOperationQueue myQueue;
    公共void调用(字符串sUrl)
    {
    会话=空;
    antwort=null;
    已完成=空;
    myQueue=新的NSOperationQueue();
    session=NSUrlSession.FromConfiguration(NSUrlSessionConfiguration.DefaultSessionConfiguration,(InsuralSessionDelegate)新SessionDelegate((erfolg,body)=>{completed(erfolg,body);}),myQueue);
    已完成+=WebserviceCallerIOS_已完成;
    尝试
    {
    请求=CreateNativePostRequest(sUrl);
    }
    捕获(例外e)
    {
    控制台写入线(e);
    已完成(false,“创建请求时出错:”+e);
    }
    dataTask=session.CreateDataTask(请求);
    dataTask.Resume();
    }
    NSMutableUrlRequest CreateNativePostRequest(字符串url)
    {
    字符串转换=((NSString)url).CreateStringByAddingPercentEscapes(NSStringEncoding.UTF8);
    var nsurl=nsurl.FromString(已转换);
    如果(nsurl==null)
    抛出新异常(“无效URL,无法从以下位置创建NSUrl:“+URL+”);
    var req=new-NSMutableUrlRequest(nsurl){HttpMethod=“GET”};
    返回请求;
    }
    私有类SessionDelegate:NSUrlSessionDataDelegate、InsuralSessionDelegate
    {
    私人行动完成(u回调);;
    私有数据;
    专用int状态代码;
    公共会话Legate(操作已完成)
    {
    已完成的回调=已完成;
    retData=新的NSData();
    }
    public override void DidReceiveResponse(NSUrlSession会话、NSUrlSessionDataTask dataTask、NSURResponse响应、操作完成处理程序)
    {
    var http_response=作为NSHTTPPURLResponse的响应;
    如果(http_响应==null)
    {
    WriteLine(“收到的非HTTP url响应:{0}',响应);
    状态代码=-1;
    返回;
    }
    status_code=(int)http_response.StatusCode;
    如果(状态代码==200)
    {
    completionHandler(NSUrlSessionResponseDisposition.Allow);
    }
    其他的
    {
    completionHandler(NSUrlSessionResponseDisposition.Cancel);
    }
    }
    公共重写void didcompletewitheror(NSUrlSession会话、NSUrlSessionTask任务、NSError错误)
    {
    已完成的_回调(错误,错误?.LocalizedDescription);
    }
    公共覆盖void DidReceiveData(NSUrlSession会话、NSUrlSessionDataTask数据任务、NSData数据)
    {
    retData=数据;
    dataTask.Suspend();
    控制台写入线(retData);
    已完成_回调(true,retData.ToString());
    }
    }
    }
    
    如果答案太长,则DidReceiveData中的NSData对象不包含所有内容。答案在1036个字符后被裁剪

    DidReceiveData
    将被触发并多次返回小数据。您必须创建全局变量来存储数据。但你的意思是数据一次超过1036个字符

    完成所有操作后,当im已经在处理接收到的数据时(无论数据是否被裁剪),就会调用DidCompleteWitheror。其中的“error”参数为null,所以我不知道为什么会调用它以及如何处理它。因此,即使我收到了DidReceiveData中的所有数据,并且一切正常,DidCompleteWitheror也会被调用


    无论请求是否成功,都会在接收到所有数据后调用didcompletewitheror。错误
    null
    表示您的请求成功。

    太棒了!这很有效。我添加了一个字符串变量“answerCache”,在DidReceiveData中,我只将接收到的数据附加到该变量。在DidCompleteWithError中,我检查错误是否为null。如果是,我调用已完成的方法,告诉它一切正常,并将整个answerCache变量传递给它。