【问题标题】:Xamarin Android httpwebrequest, Cannot access a disposed objectXamarin Android httpwebrequest,无法访问已处置的对象
【发布时间】:2017-08-16 13:34:31
【问题描述】:

我有一个 android 移动应用程序,我想向服务器发送 webrequest 以发布一些数据,但在发布数据之前我发送一个 http get 请求以获取一些数据,然后发送 post 请求, 首先我收到 get 成功,但是当我发送 post 请求时,它在我的代码requestStream.Write(bytes, 0, bytes.Length);

的这行抛出异常

例外是:

System.ObjectDisposedException:无法访问已处置的对象。 对象名称:'System.Net.Sockets.NetworkStream'。

这是我的获取和发布请求代码 获取:

public void GetTokenInfo()
        {

            try
            {
                var uri = new Uri(string.Format(_host + "webserver/SesTokInfo", string.Empty));
                var webRequest = WebRequest.Create(uri);
                using (var response = webRequest.GetResponse() as HttpWebResponse)
                {
                    using (var requestStream = response.GetResponseStream())
                    {
                        using (var reader = new StreamReader(requestStream))
                        {
                            var content = reader.ReadToEnd();
                            XmlDocument xDocument = new XmlDocument();
                            xDocument.LoadXml(content);
                            XmlElement root = xDocument.DocumentElement;
                            if (IsResponseReturned(root))
                            {
                                GlobalConfig.SessionId = root.GetElementsByTagName("SesInfo")[0].InnerText;
                                GlobalConfig.Token = root.GetElementsByTagName("TokInfo")[0].InnerText;

                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception);
            }
        }

使用此代码,我可以毫无问题地收到我的结果,这是我的 POST:

 public WebResponse PostData(string body, string url)
        {
            WebResponse webResponse = null;
            try
            {
                var uri = new Uri(string.Format(_host + url, string.Empty));
                var webRequest = (HttpWebRequest)WebRequest.Create(uri);
                webRequest.Headers.Add("Cookie",
                    GlobalConfig.SessionId);
                webRequest.Headers.Add("_RequestVerificationToken", GlobalConfig.Token);
                webRequest.Method = "POST";
                webRequest.ContentType = "application/xml";
                byte[] bytes = Encoding.UTF8.GetBytes(body);
                webRequest.ContentLength = bytes.Length;
                Stream requestStream = webRequest.GetRequestStream();
                requestStream.Write(bytes, 0, bytes.Length);
                webResponse = webRequest.GetResponse();
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
            return webResponse;
        }

我已经搜索并尝试了方法,但我没有得到解决方案,而且当我评论第一个函数并且只运行第二个函数时它会正常工作,但是当我运行第一个然后第二个时它会抛出异常,是否有任何东西属于从第一个代码中处理流和 Web 响应? 我认为 using 语句已经处理了它们。

任何帮助表示赞赏。

【问题讨论】:

    标签: c# android post xamarin webrequest


    【解决方案1】:

    这可能只是确保使用正确的using 语句的情况,因为它们会在适当的时候正确处理关闭传出和传入流。请参阅下面的修改示例,这应该适合您:

    public string PostData(string body, string url)
    {
        string responseText = null;
    
        try
        {
            var uri = new Uri(string.Format(_host + url, string.Empty));
            var webRequest = WebRequest.Create(uri) as HttpWebRequest;
    
            webRequest.Headers.Add("Cookie", GlobalConfig.SessionId);
            webRequest.Headers.Add("_RequestVerificationToken", GlobalConfig.Token);
            webRequest.Method = "POST";
            webRequest.ContentType = "application/xml";
    
            using (Stream requestStream = webRequest.GetRequestStream())
            {
                using (StreamWriter writer = new StreamWriter(requestStream))
                {
                    writer.Write(body);
                }
            }
    
            var webResponse = webRequest.GetResponse() as HttpWebResponse;
    
            using (Stream responseStream = webResponse.GetResponseStream())
            {
                using (StreamReader reader = new StreamReader(responseStream))
                {
                    responseText = reader.ReadToEnd();
                }
            }
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    
        return responseText;
    }
    

    请注意,我已将返回变量修改为字符串主体,这样您就不会潜在地打开流。

    柯达

    【讨论】:

    • 非常感谢您的回答,我使用了您的代码,但幸运的是它仍然是一样的,我想出了与 httpClient 异步使用这两个函数并工作但这种风格仍然得到相同的异常。
    【解决方案2】:
    • 您的设备/模拟器是否已连接到互联网?

    • 您的应用程序需要获得连接互联网的权限?

    • 在调用webRequest.GetResponse()之前必须关闭请求流requestStream.Close()

    • IDisposable 对象需要像GetTokenInfo() 方法一样使用using,否则会出现内存过度使用问题

    我只是测试你的代码和IT WORKS,这是我完整的测试控制台应用程序

    using System;
    using System.IO;
    using System.Net;
    using System.Text;
    
    namespace test01
    {
        class MainClass
        {
            public static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
                PostData("a", "/");
            }
    
            public static WebResponse PostData(string body, string url)
            {
                WebResponse webResponse = null;
                try
                {
                    var uri = new Uri(string.Format("http://google.it" + url, string.Empty));
                    var webRequest = (HttpWebRequest)WebRequest.Create(uri);
                    webRequest.Headers.Add("Cookie","test");
                    webRequest.Headers.Add("_RequestVerificationToken", "test");
                    webRequest.Method = "POST";
                    webRequest.ContentType = "application/xml";
                    byte[] bytes = Encoding.UTF8.GetBytes(body);
                    webRequest.ContentLength = bytes.Length;
                    Stream requestStream = webRequest.GetRequestStream();
                    requestStream.Write(bytes, 0, bytes.Length);
                    webResponse = webRequest.GetResponse();
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception);
                }
                return webResponse;
            }
        }
    }
    

    【讨论】:

    • 感谢您的回答,是的,我的设备已连接到互联网,在我调用 GetResponse 之前,它会抛出异常 requestStream.Write(bytes, 0, bytes.Length);当我写字节时,当我只运行第二种方法时它正在工作,但是当我第一次运行第一种方法然后第二种方法时它抛出异常,有什么想法吗?
    【解决方案3】:

    为了安全起见 - 尝试使用 - 而不是删除多余的

    using (var requestStream = response.GetResponseStream()) { using (var reader = new StreamReader(requestStream))

    使用

    using (var reader = new StreamReader(response.GetResponseStream())

    详情请见https://msdn.microsoft.com/library/ms182334.aspx

    【讨论】:

    • 感谢您的回答,我现在尝试了您的方法,但遇到了同样的异常。 :(
    • 在线电话你得到异常?
    • 异常出现在这一行 requestStream.Write(bytes, 0, bytes.Length);但固定见下面的答案。
    【解决方案4】:

    在尝试了多种方法并阅读了上述答案并最终尝试之后,我通过制作如下两个代码来解决问题, 得到一个:

                    var uri = new Uri(string.Format(_host + "webserver/SesTokInfo", string.Empty));
                    var webRequest = WebRequest.Create(uri);
                    using (var response = webRequest.GetResponse() as HttpWebResponse)
                    {
                        using (var reader = new StreamReader(response.GetResponseStream()))
                        {
                            var content = reader.ReadToEnd();
                            XmlDocument xDocument = new XmlDocument();
                            xDocument.LoadXml(content);
                            XmlElement root = xDocument.DocumentElement;
                            if (IsResponseReturned(root))
                            {
                                GlobalConfig.SessionId = root.GetElementsByTagName("SesInfo")[0].InnerText;
                                GlobalConfig.Token = root.GetElementsByTagName("TokInfo")[0].InnerText;
    
                            }
                        }
                    }
    

    并发布一个:

                    var uri = new Uri(string.Format(_host + url, string.Empty));
                    var webRequest2 = (HttpWebRequest)WebRequest.Create(uri);
    
    
                    webRequest2.Headers.Add("Cookie",
                        GlobalConfig.SessionId);
                    webRequest2.Headers.Add("_RequestVerificationToken", GlobalConfig.Token);
                    webRequest2.Method = "POST";
                    webRequest2.ContentType = "application/xml";
    
                    byte[] bytes = Encoding.UTF8.GetBytes(body);
                    webRequest2.ContentLength = bytes.Length;
                    StreamWriter writer = new StreamWriter(webRequest2.GetRequestStream());
                    writer.Write(bytes);
                    webResponse = webRequest2.GetResponse();
    

    当我在 using 块中使用请求流时,它仍然会抛出异常,但没有 using 块它会工作:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-23
      • 2011-03-25
      • 1970-01-01
      相关资源
      最近更新 更多