windows .Net CF / HttpWebRequest 和“WebException 未处理”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1971957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.Net CF / HttpWebRequest and a "WebException was unhandled"
提问by slowHyman2k
I′m trying to use a Webservice in a .Net Compact Framework 3.5 Project which has no WSDL and where I have to use HttpWebRequest. I′ve tried my code on 2 Devices and on the Emulator but I get everytime the same Exception and I really don′t get why!?
我正在尝试在没有 WSDL 并且我必须使用 HttpWebRequest 的 .Net Compact Framework 3.5 项目中使用 Web 服务。我已经在 2 台设备和模拟器上尝试过我的代码,但每次都遇到相同的异常,我真的不明白为什么!?
First, my code:
首先,我的代码:
internal void SendSms()
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"https://username:[email protected]/RPC2");
req.Method = @"POST";
req.ContentType = @"text/xml";
req.ContentLength = Body.Length;
using (Stream stream = req.GetRequestStream())
using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
{
writer.Write(Body);
}
using (Stream responseStream = req.GetResponse().GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
{
string result = reader.ReadToEnd();
}
}
In line "using (Stream stream = req.GetRequestStream())" I get the following exception and I can′t figure out why:
在“使用(Stream stream = req.GetRequestStream())”行中,我收到以下异常,我无法弄清楚原因:
System.Net.WebException {"Could not establish connection to network."}
System.Net.WebException {“无法建立到网络的连接。”}
Stacktrace:
堆栈跟踪:
at System.Net.HttpWebRequest.finishGetRequestStream() at System.Net.HttpWebRequest.GetRequestStream() at SipMSGate.UI.MainFormController.SendSms() at SipMSGate.UI.Form1.menuItem1_Click(Object sender, EventArgs e) at System.Windows.Forms.MenuItem.OnClick(EventArgs e) at System.Windows.Forms.Menu.ProcessMnuProc(Control ctlThis, WM wm, Int32 wParam, Int32 lParam) at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam) at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam) at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain) at System.Windows.Forms.Application.Run(Form fm) at SipMSGate.Program.Main()
在 System.Net.HttpWebRequest.finishGetRequestStream() 在 System.Net.HttpWebRequest.GetRequestStream() 在 SipMSGate.UI.MainFormController.SendSms() 在 SipMSGate.UI.Form1.menuItem1_Click(Object sender, EventArgs e) 在 System.Windows。 Forms.MenuItem.OnClick(EventArgs e) 在 System.Windows.Forms.Menu.ProcessMnuProc(Control ctlThis, WM wm, Int32 wParam, Int32 lParam) 在 System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam) 在 System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam) 在 Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain) 在 System.Windows.Forms.Application.Run(Form fm)在 SipMSGate.Program.Main()
Status:
地位:
System.Net.WebExceptionStatus.ConnectFailure
System.Net.WebExceptionStatus.ConnectFailure
I can use the Internet explorer on the Devices and on the Emulator, so I think that I have an internet Connection.
我可以在设备和模拟器上使用 Internet Explorer,所以我认为我有 Internet 连接。
Any Idea what′s wrong or what I forget in my code?
知道我的代码有什么问题或我忘记了什么吗?
Than you so much
比你多
twickl
点点滴滴
Here is now the complete Code including Yakimych's Code that gives the xception on 2 Devices and the Emulator Images which all of them are having a connection to the Internet:
现在是完整的代码,包括 Yakimych 的代码,该代码在 2 台设备和仿真器图像上提供了异常,所有这些设备都连接到 Internet:
using System.Drawing;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Windows.Forms;
namespace httpreqTest
{
public partial class Form1 : Form
{
private HttpWebRequest _req;
private bool _ignoreCertificateErrors;
private string _errorMessage;
private const string Body =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>samurai.SessionInitiate</methodName><params><param><value><struct><member><name>LocalUri</name><value><string></string></value></member><member><name>RemoteUri</name><value><string>01234556789</string></value></member><member><name>TOS</name><value><string>text</string></value></member><member><name>Content</name><value><string>This is a Test</string></value></member><member><name>Schedule</name><value><string></string></value></member></struct></value></param></params></methodCall>";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this._ignoreCertificateErrors = true;
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byte1 = encoding.GetBytes(Body);
CreateWebRequestObject(@"https://user:[email protected]/RPC2");
_req.Method = @"POST";
_req.ContentType = @"text/xml";
_req.ContentLength = byte1.Length;
using (Stream stream = _req.GetRequestStream())
using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
{
writer.Write(Body);
}
using (Stream responseStream = _req.GetResponse().GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
{
string result = reader.ReadToEnd();
}
}
public bool CreateWebRequestObject(string Url)
{
try
{
this._req = (HttpWebRequest)System.Net.WebRequest.Create(Url);
if (this._ignoreCertificateErrors)
ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
}
catch (Exception ex)
{
this._errorMessage = ex.Message;
return false;
}
return true;
}
/// <summary>
/// Internal object used to allow setting WebRequest.CertificatePolicy to
/// not fail on Cert errors
/// </summary>
internal class AcceptAllCertificatePolicy : ICertificatePolicy
{
public AcceptAllCertificatePolicy()
{
}
public bool CheckValidationResult(ServicePoint sPoint, X509Certificate cert, WebRequest wRequest, int certProb)
{
// *** Always accept
return true;
}
}
}
}
}
回答by Pent Ploompuu
You are passing the wrong value to the Content-Length header. It should be the length of the content in bytesnot the count of unicode characters in the string (StreamWriter
also adds the UTF8 preamble). I recommend not using the preamble and converting the string to a byte array before setting the Content-Length header value. Also, passing the username and password using the req.Credentials
property might be a good idea.
您将错误的值传递给 Content-Length 标头。它应该是内容的长度(以字节为单位)而不是字符串中的 unicode 字符数(StreamWriter
还添加了 UTF8 前导码)。我建议在设置 Content-Length 标头值之前不要使用前导码并将字符串转换为字节数组。此外,使用req.Credentials
属性传递用户名和密码可能是一个好主意。
internal void SendSms()
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"https://api.sipgate.net/RPC2");
req.Credentials = new NetworkCredential("username", "password");
req.Method = @"POST";
req.ContentType = @"text/xml";
byte[] data = Encoding.UTF8.GetBytes(Body);
req.ContentLength = data.Length;
using(Stream stream = req.GetRequestStream())
stream.Write(data, 0, data.Length);
using(Stream responseStream = req.GetResponse().GetResponseStream())
using(StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
{
string result = reader.ReadToEnd();
}
}
回答by Yakimych
Indeed, when using https, you need to validate the certificate. To do that, create an AcceptAllCertificatePolicy class and set the certificate policy BEFORE your code: ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
确实,在使用 https 时,您需要验证证书。为此,请创建一个 AcceptAllCertificatePolicy 类并在您的代码之前设置证书策略: ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
You can find a sample and the class code here: http://www.west-wind.com/weblog/posts/48909.aspx
您可以在此处找到示例和课程代码:http: //www.west-wind.com/weblog/posts/48909.aspx
See if this solves the problem.
看看这是否能解决问题。
回答by Nick Berardi
I don't think HTTP/HTTPS supports the same username password constructs in the URL as FTP does. If you are trying to do basic authentication you need to pass those in through the header. Try this:
我认为 HTTP/HTTPS 不支持 URL 中与 FTP 相同的用户名密码结构。如果您尝试进行基本身份验证,则需要通过标头传递这些内容。尝试这个:
req.Credentials = new NetworkCredential("username","password");
This will pass along the "Basic Authentication" credentials to the web host. You can read more about it here:
这会将“基本身份验证”凭据传递给 Web 主机。你可以在这里读更多关于它的内容:
http://msdn.microsoft.com/en-us/library/system.net.networkcredential.aspx
http://msdn.microsoft.com/en-us/library/system.net.networkcredential.aspx
回答by slowHyman2k
I got the same error. You have to call
我得到了同样的错误。你必须打电话
WebResponse ws = request.GetResponse();
// do some stuff
ws.close();
With using(Stream responseStream = req.GetResponse().GetResponseStream())
, you create a WebResponse
, but you don't close it. On mobile devices it leads fast to a time-out exception.
使用using(Stream responseStream = req.GetResponse().GetResponseStream())
,您可以创建一个WebResponse
,但不要关闭它。在移动设备上,它会很快导致超时异常。