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())
在尝试了很多方法并阅读了上面的答案并尝试之后,我终于通过将这两种代码都写成如下所示解决了问题,
获得一个:
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 块的情况下它会工作:)
我有一个 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())
在尝试了很多方法并阅读了上面的答案并尝试之后,我终于通过将这两种代码都写成如下所示解决了问题, 获得一个:
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 块的情况下它会工作:)