Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Posting using POST from C# over https

After wasting two days with this question (and trying to make it work), I've decided to take a step back and ask a more basic question, because apparently there's something I don't know or I'm doing wrong.

The requirements are simple, I need to make an HTTP post (passing a few values) over https from C#.

The website (if given the appropriate values) will return some simple html and a response code. (i'll show these later).

It's really that simple. The "webservice" works. I have a php sample that works and successfully connects to it. I also have a Dephi "demo" application (with source code) that also works. And finally I have the demo application (binary) from the company that has the "service", that also works of course.

But I need to do it through C#. That that sounds so simple, it is not working.

For testing purposes I've created a simple console app and a simple connect method. I've tried like 7 different ways to create an HTTP request, all more or less the same thing, different implementation (Using WebClient, using HttpWebRequest, etc).

Every method works, except when the URI begins with 'https'.

I get a webexception saying that the remote server returned 404. I've installed Fiddler (as suggested by a SO user), and investigated a little bit the traffic. The 404 is because I am passing something wrong, because as I mentioned later, the 'service' works. I'll talk about the fiddler results later.

The URL where I have to POST the data is: https://servicios.mensario.com/enviomasivo/apip/

And this is the POST data: (the values are fakes)

usuario=SomeUser&clave=SomePassword&nserie=01234567890123456789&version=01010000&operacion=220

The server might return a two/three lines response (sorry about the spanish, but the company is from Spain). Here's a sample of a possible response:

HTTP/1.1 200 OK
Content-Type: text/plain

01010000 100 BIEN
998

And here's another

HTTP/1.1 200 OK
Content-Type: text/plain

01010000 20 AUTENTIFICACION NEGATIVA
Ha habido un problema en la identificación ante el servidor. Corrija sus datos de autentificacion.

The 1st one means OK, and the 2nd one is Auth Failure.

As you can see the task is quite easy, only it doesn't work. If I use fiddler, I see that there's some sort of SSL stuff going on in the connection and then everything works fine. However, as far as I've read, .NET handles all that stuff for us (yes, i've added the callback to always validate invalid certs). I don't understand what I'm doing wrong. I can post/email the code, but what I'd like to know is very simple:

How can you make a POST over SSL using C# and a "simple" HttpWebRequest and later have the response in a string/array/Whatever for processing?

Trust me when I say I've been googling and Stackoverflowing for two days. I don't have any sort of proxy. The connection passes through my router. Standard ports. Nothing fancy. My Machine is inside a VMWare virtual machine and is Windows Vista, but given that the sample applications (php, delphi, binary) all work without an issue, I cannot see that as a problem).

The different samples (sans the binary) are available here if anyone wants to take a look at them.

I'd appreciate any help. If anyone wants to try with a "real" username, I have a demo user and I could pass you the user/pass for testing purposes. I only have one demo user (the one they gave me) and that's why I'm not pasting it here. I don't want to flood the user with tests ;)

I've tried (within the samples) using UTF8 and ASCII, but that didn't change anything.

I am 100% positive that there's something I have to do with SSL and I am not doing it because I don't know about it.

Thanks in advance.

Martín.

like image 538
Martin Marconcini Avatar asked Apr 21 '09 17:04

Martin Marconcini


People also ask

How do you send data using POST method?

To send data using the HTTP POST method, you must include the data in the body of the HTTP POST message and specify the MIME type of the data with a Content-Type header. Below is an example of an HTTP POST request to send JSON data to the server. The size and data type for HTTP POST requests is not limited.

What is the POST method?

POST Method: In the POST method, the data is sent to the server as a package in a separate communication with the processing script. Data sent through the POST method will not be visible in the URL. The query string (name/weight) is sent in the HTTP message body of a POST request.

What is POST method in C#?

The POST Method POST is used to send data to a server to create/update a resource. The data sent to the server with POST is stored in the request body of the HTTP request: POST /test/demo_form.php HTTP/1.1.

What is difference between put and POST?

Use PUT when you want to modify a single resource which is already a part of resources collection. PUT overwrites the resource in its entirety. Use PATCH if request updates part of the resource. Use POST when you want to add a child resource under resources collection.


2 Answers

I was battling with the exact same problem a bit earlier (although in compact framework). Here's my question and my own answer to it: Asynchronous WebRequest with POST-parameters in .NET Compact Framework

My version is asynchronous, so it's a bit more complex than what you're looking for, but the idea remains.

private string sendRequest(string url, string method, string postdata) {
    WebRequest rqst = HttpWebRequest.Create(url);

    // only needed, if you use HTTP AUTH
    //CredentialCache creds = new CredentialCache();
    //creds.Add(new Uri(url), "Basic", new NetworkCredential(this.Uname, this.Pwd));
    //rqst.Credentials = creds;
    rqst.Method = method;
    if (!String.IsNullOrEmpty(postdata)) {
        //rqst.ContentType = "application/xml";
        rqst.ContentType = "application/x-www-form-urlencoded";

        byte[] byteData = UTF8Encoding.UTF8.GetBytes(postdata);
        rqst.ContentLength = byteData.Length;
        using (Stream postStream = rqst.GetRequestStream()) {
            postStream.Write(byteData, 0, byteData.Length);
            postStream.Close();
        }
    }
    ((HttpWebRequest)rqst).KeepAlive = false;
    StreamReader rsps = new StreamReader(rqst.GetResponse().GetResponseStream());
    string strRsps = rsps.ReadToEnd();
    return strRsps;

}
like image 178
Tommi Forsström Avatar answered Oct 06 '22 18:10

Tommi Forsström


see my answer to your other question. I believe your problem may not be your C# code. The web service URL accually returns a 404 with several other tools I used, but it returns the response you indicated if you leave off the trailing slash from the web service URL, so I suggest trying that.

Oddly, it doesn't seem to matter if the trailing URL is there when not doing SSL. Something strange with that web server, I guess.

like image 32
Erv Walter Avatar answered Oct 06 '22 16:10

Erv Walter