Вызвать веб-метод, зная только Endpoint
Настал такой момент, когда я не могу добавить в проект ссылку на веб-сервис посредством Service Reference - просто потому, что я её не знаю, а получаю каждый раз от клиента, и на неё нужно отправить результат.
Разобравшись с тем, как это сделать, решил написать конкретный пример для статьи Send Data Using the WebRequest Class.
Итак, допустим, у нас есть множество клиентов, которые шлют нам асинхронные запросы, а мы должны после обработки отправлять им ответ каждому на его адрес. Статически прописать эти адреса в конфиге мы, очевидно, не можем. Потому адрес для ответа они нам присылают сами вместе с запросом.
Разумеется, набор входных параметров веб-метода, который принимает от нас результат, одинаков для всех клиентов. Ну и значит достаточно научиться отвечать на один - с остальными будет всё то же самое, только разный адрес.
Скажем, адрес веб-метода первого клиента такой: http://someDomain:34543/someService.asmx?op=someMethod. Открываем эту ссылку в браузере и видим подсказку, как его вызывать:
Здесь показаны примеры вызова и ответа (залиты жёлтым фоном) по различным протоколам. Я взял вызов SOAP 1.1 - его вы и видите на скриншоте.
Теперь в проекте, который будет отправлять результаты, пишем саму отправку:
// в качестве ссылки подставляется адрес для текущего клиента, который он присылал с запросом
var theWebRequest = HttpWebRequest.Create("http://someDomain:34543/someService.asmx?op=someMethod");
// этот XML в точности соответствует тому, который мы видели в подсказке сервиса
// хотя у меня там замазаны названия, я надеюсь, вы разберётесь
string requestXML = new StringBuilder()
.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
.Append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">")
.Append("<soap:Body>")
.Append("<someMethod xmlns=\"http://tempuri.org/\">")
.Append(string.Format("<idRequestFromSender>{0}</idRequestFromSender>", 3000)) // например, 3000
.Append(string.Format("<xmlResult>{0}</xmlResult>", "ololo")) // например, ololo
.Append("</someMethod>")
.Append("</soap:Body>")
.Append("</soap:Envelope>").ToString();
// эти значения также берутся из подсказки
theWebRequest.Method = "POST";
theWebRequest.ContentType = "text/xml; charset=utf-8";
byte[] bytes = Encoding.UTF8.GetBytes(requestXML.ToString());
theWebRequest.ContentLength = bytes.Length;
using (var dataStream = theWebRequest.GetRequestStream())
{
dataStream.Write(bytes, 0, bytes.Length);
}
// на случай, если сервисы клиента требуют аутентификации
theWebRequest.Credentials = new NetworkCredential("yourLogin", "yourPassword");
// отправляем
var theWebResponse = (HttpWebResponse)theWebRequest.GetResponse();
// если веб-методы клиентов что-то возвращают, то можно посмотреть
var theResponseStream = new StreamReader(theWebResponse.GetResponseStream());
string result = theResponseStream.ReadToEnd().ToString();
Social networks
Zuck: Just ask
Zuck: I have over 4,000 emails, pictures, addresses, SNS
smb: What? How'd you manage that one?
Zuck: People just submitted it.
Zuck: I don't know why.
Zuck: They "trust me"
Zuck: Dumb fucks