使用 POST 从 C# 通过 https 发布

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/773638/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 00:36:23  来源:igfitidea点击:

Posting using POST from C# over https

c#.netsslposthttpwebrequest

提问by Martin Marconcini

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 httpsfrom C#.

要求很简单,我需要从 C#通过 https 制作一个 HTTP 帖子(传递一些值)

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

该网站(如果给出适当的值)将返回一些简单的 html 和响应代码。(我稍后会展示这些)。

It's really thatsimple. 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.

真的就是这么简单。“网络服务”有效。我有一个可以运行并成功连接到它的 php 示例。我还有一个同样有效的 Dephi“演示”应用程序(带有源代码)。最后我有来自公司的演示应用程序(二进制),它有“服务”,当然也可以使用。

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

但我需要通过 C# 来完成。这听起来很简单,但它行不通。

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

出于测试目的,我创建了一个简单的控制台应用程序和一个简单的连接方法。我已经尝试了 7 种不同的方法来创建 HTTP 请求,或多或少都是一样的,不同的实现(使用 WebClient,使用 HttpWebRequest 等)。

Every method works, exceptwhen the URI begins with 'https'.

每种方法都有效,除非URI 以“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.

我收到一个 web 异常,说远程服务器返回 404。我已经安装了 Fiddler(按照 SO 用户的建议),并调查了一些流量。404 是因为我传递了错误的信息,因为正如我稍后提到的,“服务”有效。稍后我将讨论提琴手的结果。

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

我必须发布数据的 URL 是:https: //servicios.mensario.com/enviomasivo/apip/

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

这是 POST 数据:(值是假的)

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

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.

第一个表示 OK,第二个是 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:

正如您所看到的,任务很简单,只是它不起作用。如果我使用 fiddler,我会看到连接中存在某种 SSL 内容,然后一切正常。但是,据我所知,.NET 为我们处理了所有这些事情(是的,我已经添加了回调以始终验证无效证书)。我不明白我做错了什么。我可以发布/通过电子邮件发送代码,但我想知道的很简单:

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?

如何使用 C# 和“简单” HttpWebRequest 通过 SSL 进行 POST,然后在字符串/数组/任何处理中获得响应?

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

当我说我已经使用谷歌搜索和 Stackoverflowing 两天时,请相信我。我没有任何代理。连接通过我的路由器。标准端口。没有什么花哨。我的机器位于 VMWare 虚拟机中,并且是 Windows Vista,但鉴于示例应用程序(php、delphi、二进制)都可以正常运行,我认为这不是问题)。

The different samples (sans the binary) are available hereif 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 onedemo 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.

我已经尝试过(在示例中)使用 UTF8 和 ASCII,但这并没有改变任何东西。

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.

我 100% 肯定我与 SSL 有关系,但我没有这样做,因为我不知道它。

Thanks in advance.

提前致谢。

Martín.

马丁。

采纳答案by Erv Walter

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.

看到我对你的另一个问题的回答。我相信您的问题可能不是您的 C# 代码。Web 服务 URL 与我使用的其他几个工具一起返回 404,但如果您从 Web 服务 URL 中删除尾部斜杠,它会返回您指示的响应,因此我建议尝试这样做。

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.

奇怪的是,在不执行 SSL 时,尾随 URL 是否存在似乎无关紧要。我猜那个网络服务器有些奇怪。

回答by Tommi Forsstr?m

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

我早些时候正在与完全相同的问题作斗争(尽管在紧凑的框架中)。这是我的问题和我自己的答案: 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;

}

回答by jorge

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.

不知道你是否已经解决了这个问题,这是一年前的帖子。我是西班牙人,我也在使用 mensario。

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

发送和http请求:(这是在ASP中,但过程是相同的)

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

基本上,当响应为“100 bien”时,函数返回该值,否则返回错误。希望有帮助:)