Posting using POST from C# over https

2019-02-12 15:21发布

问题:

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.

回答1:

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.



回答2:

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;

}


回答3:

dont know if u already resolved this issue, it´s a post from one year ago. I am Spanish and I am using mensario too.

to send and http request: (this is in ASP but the process is the same one)

Function enviarMsg2
   Dim oHTTP,inicio
   Dim strParametros
   Dim devolver

   Set oHTTP= server.CreateObject("Msxml2.ServerXMLHTTP")
   strParametros = "usuario="&usuario&"&clave="&clave&"&nserie="&nserie&"&     version=01010000&operacion=300&sms=1%0934635035526%0920041231233000%09Clinica+Paz%09Clinica+Paz+le+desea+Feliz+Navidad%2E&sms=2%0934612345678%0920041231233001%09Clinica+Paz%09Clinica+Paz+le+desea+Feliz+Navidad%2E"
'response.Write strParametros
'response.End
'Abrimos la conexión con el método POST, ya que estamos enviando una petición.
oHTTP.open "POST", "https://servicios.mensario.com/enviomasivo/apip", False

'Agregamos encabezados HTTP requeridos...
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"

'Enviamos la petición
oHTTP.send strParametros
devolver = oHTTP.responsetext

'Comprobamos si fue correcto         
inicio = Instr(devolver, "100 BIEN")
'response.Write "--->"&inicio
'response.End    
if inicio <=0 then
  enviarSMS2 = "Ha ocurrido un error en el envío del SMS."
else
  enviarSMS2 = Mid(devolver,inicio+9,len(devolver))
end if

Set oHTTP = Nothing

The only thing i dont have is a user /password for a try :)

Basicaly, when the response is "100 bien" the function returns that, otherwise it returns error.Hope it helps :)