2015-03-27 2 views
2

Я работаю над проектом, где мне нужно вызвать API в форме веб-сервиса SOAP и получить ответ. Когда ответ возвращается, есть значение Set-Cookie, которое я должен извлечь из заголовка и передать его в заголовке Cookie с последующими запросами API. Первоначально я строю свой документ SOAP с нуля, используя XmlWriter. Один из моих товарищей помог мне использовать Service Reference, что означало, что мне не нужно было писать какой-либо пользовательский XML (BIG WIN).Получить значение заголовка (Set-Cookie) из ответа службы CallReference

Моя основная проблема заключается в том, что мне нужно получить значение заголовка, без этого вызовы API не будут работать. Есть ли способ получить заголовок ответа, все еще имея возможность использовать Service Reference и все, что приходит с ним?

+0

Это довольно тупой API. Заголовки SOAP следует использовать вместо файлов cookie. Заголовки SOAP могут использоваться независимо от базового транспортного протокола, но файлы cookie будут работать только с HTTP. –

ответ

1

Я потратил большую часть дня, пытаясь понять это ... Я закончил тем, что написал службу WCF, чтобы смоделировать настройку cookie и отправить ее как часть OperationContract (хотя это плохая практика, Практически, поскольку WCF не является только HTTP).

Первоначально я думал, что инспекторы сообщений будут делать трюк, однако после нескольких часов повторения кода я в конечном итоге написал собственный класс WebClient, чтобы «имитировать» ссылку на службу, что позволило мне увидеть заголовки в CookieContainer.

Итак, пробовав все эти разные идеи и нарисуя страницы и страницы кода, как обычно, я пытаюсь сделать что-то, чего раньше не делал, наткнулся на статью в google (в то время как искал что-то совершенно отличное от оригинала проблема):

http://megakemp.com/2009/02/06/managing-shared-cookies-in-wcf/

Прочитайте раздел (Ad-Hoc управление печенья), вот моя реализация (с помощью тест-службы, который я создал, чтобы имитировать вашу проблему). Вы могли бы сделать больше вменяемости/ошибки проверки на участке, где я вновь собрать печенье из строки заголовка ...

 List<string> strings = null; 

     // Using Custom Bindings to allow Fiddler to see the HTTP interchange. 
     BasicHttpBinding binding = new BasicHttpBinding();    
     binding.AllowCookies = true; 
     binding.BypassProxyOnLocal = false; 
     binding.ProxyAddress = new Uri("http://127.0.0.1:8888"); 
     binding.UseDefaultWebProxy = false; 

     EndpointAddress url = new EndpointAddress("http://192.168.20.4:42312/Classes/TestService.svc"); 

     using (TestServiceClient client = new TestServiceClient(binding,url)) 
     {     
      using (new OperationContextScope(client.InnerChannel)) 
      { 
       strings = new List<string>(client.WSResult()); 
       HttpResponseMessageProperty response = (HttpResponseMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name]; 

       CookieCollection cookies = new CookieCollection(); 
       foreach (string str in response.Headers["Set-Cookie"].ToString().Split(";".ToCharArray())) 
       { 
        Cookie cookie = new Cookie(str.Split("=".ToCharArray())[0].Trim(), str.Split("=".ToCharArray())[1].Trim()); 
        cookies.Add(cookie); 
       } 
      } 

     } 
+0

Я не использовал все это и фактически нашел [эту статью MSDN] (https://msdn.microsoft.com/en-us/library/system.servicemodel.wshttpbinding.allowcookies%28v=vs.110%29 .aspx), которые использовали аналогичный подход. Мне не нужен «CookieCollection». Я просто схватил «ответ» так же, как вы делали выше, но затем смог использовать 'response.Headers [" Set-Cookie "]' для захвата значения. – dstepan

1

Так что я провел еще некоторое время копать, искать, возиться с MessageBehavior с и веб .config, и, наконец, нашел то, что решило то, что мне нужно. Я отметил ответ выше, как ответ на этот вопрос, потому что он достаточно близко к тому, как я решил свою проблему, но я думаю, что способ, которым я это сделал, немного чище и отличается от приведенного выше ответа, чтобы гарантировать больше, чем комментарий ,

От this MSDN article вы можете использовать OperationContextScope для проверки ответа и добавления значений к следующему запросу.

Мой код закончился выглядеть так:

string sharedCookie = string.Empty; 

using (MyClient client = new MyClient()) 
{ 
    client.RequestThatContainsCookieValue(); 

    // This gets the response context 
    HttpResponseMessageProperty response = (HttpResponseMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name]; 

    sharedCookie = response.Headers["Set-Cookie"]; 

    // Create a new request property 
    HttpRequestMessageProperty request = new HttpRequestMessageProperty(); 

    // And add the cookie to the Header 
    request.Headers["Cookie"] = sharedCookie; 

    // Add the new request properties to the outgoing message 
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = request; 

    var response = client.ThisCallPassesTheCookieInTheHeader(); 
} 
+0

Рад, что вам удалось получить то, что вам нужно! Я не понимал, что вы хотите отправить файл cookie в качестве части вашего запроса. Причина, по которой я создал куки-контейнер, заключается в том, что, используя эту реализацию, я могу передать контейнер из вызова webservice на вызов HTTP POST с использованием REST API или какой-либо другой службы, отличной от WCF/non-SOAP, поэтому я не пойман в ловушку только используя инфраструктуру ServiceReference. Спасибо за голосование/ответ, хотя! –

Смежные вопросы