Xamarin Android httpwebrequest,无法访问已处置的对象

Xamarin Android httpwebrequest, Cannot access a disposed object

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

这行抛出异常

例外情况是:

System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Sockets.NetworkStream'.

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

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;
        }

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

感谢任何帮助。

  • 你的 device/emulator 连接到互联网了吗?

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

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

  • 在你的GetTokenInfo()方法中需要对IDisposable对象使用using,否则你会遇到内存过度使用的问题

我只是测试你的代码,它工作正常,这是我的完整测试控制台应用程序

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;
        }
    }
}

这可能只是确保使用正确的 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;
}

请注意,我已将 return 变量修改为字符串主体,这样您就不会潜在地让流处于打开状态。

幸田

为了安全起见 - 尝试使用 - 而不是

删除额外的内容

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

在尝试了很多方法并阅读了上面的答案并尝试之后,我终于通过将这两种代码都写成如下所示解决了问题, 获得一个:

                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;

                        }
                    }
                }

和POST一个:

                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 块的情况下它会工作:)