【问题标题】:Posting using POST from C# over https通过 https 使用 C# 中的 POST 发布
【发布时间】:2010-10-20 21:26:02
【问题描述】:

this question 浪费了两天时间(并试图让它发挥作用)之后,我决定退后一步,问一个更基本的问题,因为显然有些事情我不知道或者我正在做错误的。

要求很简单,我需要在 C# 中通过 https 发布一个 HTTP 帖子(传递一些值)。

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

真的那么简单。 “网络服务”有效。我有一个可以正常工作并成功连接到它的 php 示例。我还有一个也可以工作的 Dephi“演示”应用程序(带有源代码)。最后,我有来自具有“服务”的公司的演示应用程序(二进制),当然也可以。

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

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

所有方法都有效,除了当 URI 以“https”开头时。

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

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

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

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

服务器可能会返回两/三行响应(对不起,西班牙语,但公司来自西班牙)。以下是可能的响应示例:

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

01010000 100 BIEN
998

还有一个

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.

第一个代表OK,第二个代表Auth Failure。

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

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

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

如果有人想查看它们,可以使用here 获取不同的样本(无二进制文件)。

如果有任何帮助,我将不胜感激。如果有人想尝试使用“真实”用户名,我有一个演示用户,我可以将用户/通行证传递给您以进行测试。我只有 一个 演示用户(他们给我的那个),这就是我不在这里粘贴它的原因。我不想用测试淹没用户;)

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

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

感谢提前

马丁。

【问题讨论】:

    标签: c# .net ssl post httpwebrequest


    【解决方案1】:

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

    发送和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
    

    我唯一没有的是用户/密码尝试:)

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

    【讨论】:

    • 感谢 Jorge 的回复,我们已经解决了这个问题。问题是mensario url末尾有一个“/”,这是不正确的。
    【解决方案2】:

    我早些时候曾与完全相同的问题作斗争(尽管在紧凑的框架中)。这是我的问题和我自己的答案: Asynchronous WebRequest with POST-parameters in .NET Compact Framework

    我的版本是异步的,所以它比你要找的要复杂一些,但这个想法仍然存在。

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

    【讨论】:

    • 您好,Tommi,感谢您提供的示例。不幸的是,它似乎也不适合我。您的代码中有两个拼写错误(您在创建 StreamReader 时使用了“req”,我认为它是 rqst?然后我认为 streamIn 是 rsps(接近尾声)。尽管如此,我仍然在该行中得到 404: StreamReader rsps = new StreamReader(req.GetResponse().GetResponseStream()); 问题:如果我不想使用 Credentials,我可以跳过那个吗?我做了但是没有用。这个服务不需要. 用户/通行证
    • 天啊,错别字很抱歉。我会立即在答案中修复它们。如果你得到的是 404,那么问题不在于代码,你只是发送了错误的 url。在发送请求的代码中放置一些断点,并双重检查您提供的 Uri 构造函数的 url 是否有效。是的,当然你可以跳过证书部分,我会评论出来!
    • 哦,另外,当您发送常规 POST 参数时,我需要将内容类型更改为“application/x-www-form-urlencoded”。就我而言,我在 post params 字段中发送 XML,它要求使用该内容类型。
    • 谢谢 Tommi,正如您所指出的,这是 URL 的问题(有一个结尾斜杠)。 :) 感谢您的代码 :) 我一定会使用它。
    • 我建议检查在我的答案中提供的链接中找到的异步版本。在发送(可能是缓慢的)网络请求时,在检索数据时让主线程保持良好和响应总是一件好事。
    【解决方案3】:

    请参阅我对您其他问题的回答。我相信您的问题可能不是您的 C# 代码。 Web 服务 URL 与我使用的其他几个工具一起实际返回 404,但如果您从 Web 服务 URL 中去掉尾部斜杠,它会返回您指示的响应,所以我建议尝试一下。

    奇怪的是,当不使用 SSL 时,尾随 URL 是否存在似乎并不重要。我猜那个网络服务器有点奇怪。

    【讨论】:

    • Erv,就是这样!非常感谢。 (感谢其他海报的样本,我一定会混合使用所有这些。你是我的英雄,正如我在另一个问题中所说的那样。:)
    • 寓意故事:总是三重检查“其他开发人员”告诉你的内容。 (Web 服务器程序员坚持认为 URL 有斜线,我相信他)。 :S
    猜你喜欢
    • 1970-01-01
    • 2013-02-01
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多