Публикация с использованием POST из C# через https
Потратив два дня на этот вопрос (и пытаясь заставить его работать), я решил сделать шаг назад и задать более простой вопрос, потому что, очевидно, что-то я не знаю или делаю неправильно.
Требования просты, мне нужно сделать HTTP-пост (передавая несколько значений) через https из C#.
Веб-сайт (при наличии соответствующих значений) вернет простой HTML-код и код ответа. (я покажу это позже).
Это действительно так просто. "Вебсервис" работает. У меня есть пример PHP, который работает и успешно подключается к нему. У меня также есть демо-приложение Dephi (с исходным кодом), которое также работает. И, наконец, у меня есть демонстрационное приложение (бинарное) от компании, которая имеет "сервис", который также работает, конечно.
Но мне нужно сделать это через C#. То, что звучит так просто, это не работает.
Для тестирования я создал простое консольное приложение и простой метод подключения. Я пробовал 7 разных способов создания HTTP-запроса, все более или менее одинаково, разные реализации (использование WebClient, использование HttpWebRequest и т. Д.).
Каждый метод работает, кроме случаев, когда URI начинается с "https".
Я получаю исключение, в котором говорится, что удаленный сервер вернул 404. Я установил Fiddler (как предложил пользователь SO) и немного исследовал трафик. 404 - потому что я пропускаю что-то не так, потому что, как я упоминал позже, "сервис" работает. О результатах скрипача я расскажу позже.
URL, по которому я должен отправить данные: https://servicios.mensario.com/enviomasivo/apip/
И это данные POST: (значения являются подделками)
=SomeUser Новичок & клаве =SomePassword&nserie=01234567890123456789& версия =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.
Первый означает ОК, а второй - Отказ аутентификации.
Как видите, задача довольно проста, только она не работает. Если я использую fiddler, я вижу, что в соединении происходит что-то вроде SSL, а затем все работает нормально. Однако, насколько я прочитал, .NET обрабатывает все эти вещи для нас (да, я добавил обратный вызов, чтобы всегда проверять недействительные сертификаты). Я не понимаю, что я делаю не так. Я могу отправить / отправить код по электронной почте, но то, что я хотел бы знать, очень просто:
Как вы можете сделать POST поверх SSL с использованием C# и "простого" HttpWebRequest, а затем получить ответ в виде строки / массива / Что бы ни обрабатывалось?
Поверь мне, когда я скажу, что гуглю и переполняю два дня. У меня нет никакого прокси. Соединение проходит через мой роутер. Стандартные порты. Ничего фантастического. Моя машина находится внутри виртуальной машины VMWare и работает под управлением Windows Vista, но, учитывая, что примеры приложений (php, delphi, binary) работают без проблем, я не вижу в этом проблем).
Различные образцы (без двоичного кода) доступны здесь, если кто-то хочет взглянуть на них.
Буду признателен за любую помощь. Если кто-то захочет попробовать "настоящее" имя пользователя, у меня есть демонстрационный пользователь, и я мог бы передать вам пользователя / пройти для целей тестирования. У меня есть только один демонстрационный пользователь (тот, который они мне дали), и поэтому я здесь его не вставляю. Я не хочу наводнить пользователя тестами;)
Я пробовал (в примерах) использовать UTF8 и ASCII, но это ничего не изменило.
Я на 100% уверен, что есть что-то, что я должен делать с SSL, и я не делаю этого, потому что я не знаю об этом.
Заранее спасибо
Мартин.
3 ответа
См. мой ответ на ваш другой вопрос. Я полагаю, что вашей проблемой может быть не ваш код C#. URL веб-службы обычно возвращает 404 с несколькими другими инструментами, которые я использовал, но он возвращает ответ, который вы указали, если не указывать косую черту в URL-адресе веб-службы, поэтому я предлагаю попробовать это.
Как ни странно, это не имеет значения, если есть конечный URL, когда вы не используете SSL. Наверное, что-то странное с этим веб-сервером.
Я боролся с точно такой же проблемой чуть раньше (хотя и в компактных рамках). Вот мой вопрос и мой собственный ответ на него: Асинхронный WebRequest с POST-параметрами в.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;
}
Не знаю, если вы уже решили эту проблему, это сообщение год назад. Я испанец, и я тоже использую 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", функция возвращает его, в противном случае возвращает ошибку. Надеюсь, это поможет:)