views:

491

answers:

6

Hello,

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!?

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:

System.Net.WebException {"Could not establish connection to network."}

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

Status:

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.

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:

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

}

+1  A: 

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

You can find a sample and the class code here: http://www.west-wind.com/weblog/posts/48909.aspx

See if this solves the problem.

Yakimych
Hi,I´ve tried your code but it does not solve my Problem. I get the same Exception overall. Any mor Ideas? IS there a way to check if this is a certification Problem. Because the Exception is still "Could not establish connection to network." although I have an Internetconnection on my Devices established. Tried it with an 2.0 and 3.5 Compact Framework Project.
twickl
First, check if you can do regular http:// connections. That would rule out the internet connection issue. Just because IE can connect, doesn't mean a .net app can connect.
Cheeso
A: 

Get a tracelog of this failure, and put it on pastebin.com, where we can take a look.

Instructions here:

http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html

Can you ping the destination from the smart device emulator? Can you telnet to port 443 on the destination (api.sipgate.net) from the emulator?

feroze
Thx for your reply. I will try that!Telnet in the emulator? Do you mean by installing something like putty in the Emulator or in my Code?
twickl
+1  A: 

shouldn't your content type be text/xml ??

Bryan
Yeah, sorry...I´ve corrected that but has no effect on my Problem.
twickl
+1  A: 

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:

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:

http://msdn.microsoft.com/en-us/library/system.net.networkcredential.aspx

Nick Berardi
+1  A: 

You are passing the wrong value to the Content-Length header. It should be the length of the content in bytes not 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.

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();
 }
}
Pent Ploompuu
A: 
slowjack2k