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

时间:2017-08-16 13:34:32

标签: c# android post xamarin webrequest

我有一个Android移动应用程序,我想发送webrequest到服务器发布一些数据,但在发布数据之前我发送一个http获取请求来获取一些数据,然后发送帖子请求, 首先我收到成功,但当我发送邮件请求时,它会抛出我的代码requestStream.Write(bytes, 0, bytes.Length);

这一行的例外情况

例外是:

  

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

这是我的get和post请求代码 GET:

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响应? 我认为使用声明已经处理它们了。

任何帮助表示感谢。

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

  • 您的设备/模拟器是否已连接到互联网?

  • 您的申请是否需要获得连接互联网的权限?

  • 您必须在致电requestStream.Close()

  • 之前关闭请求流webRequest.GetResponse()
  • using方法需要使用GetTokenInfo() IDisposable对象,否则会出现内存过度使用问题

我只是测试你的代码和 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;
        }
    }
}

答案 2 :(得分:1)

只是为了安全 - 尝试删除额外使用 - 而不是

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

答案 3 :(得分:1)

在尝试了很多方法并阅读上面的答案并最终尝试后,我通过使两个代码如下所示解决问题,  得到一个:

                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();

当我在使用块内部使用请求流时,它仍然会抛出异常,但是如果没有使用块它将起作用:)