Declaration of VAR

and some other stuff

Вызвать веб-метод, зная только Endpoint

2015-05-09 20:43:22 +0300

2015-05-09 20:43:22 +0300 | Comments

Настал такой момент, когда я не могу добавить в проект ссылку на веб-сервис посредством 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();