从ServiceReference调用的响应中获取标头值(Set-Cookie)

时间:2015-03-27 14:56:47

标签: c# .net soap

我正在开发一个项目,我必须在SOAP Web服务表单中调用API并获得响应。当响应返回时,我必须从标头中提取Set-Cookie值,并在标头Cookie值中传递随后的API请求。最初,我使用XmlWriter从头开始构建我的SOAP文档。我的一个队友让我使用服务参考,这意味着我没有必要编写任何自定义XML(BIG WIN)。

我的主要问题是我必须获取标头值,否则API调用将无法正常工作。有没有办法获得响应标题,同时仍然能够使用服务参考及其附带的所有好处?

2 个答案:

答案 0 :(得分:1)

我花了大部分时间试图弄清楚这个...我最后编写了一个WCF服务来模拟设置一个cookie并将其作为OperationContract的一部分发送出去(虽然这是不好的做法,我不会这样做'实际上,因为WCF不仅仅是HTTP。)

最初我认为Message Inspectors可以解决问题,但是经过几个小时的代码迭代后,我最终编写了一个自定义WebClient类来“模拟”服务引用,这使我能够在CookieContainer中看到Headers。 / p>

所以在尝试了所有这些不同的想法并编写页面和代码页之后,我大多数时候尝试过以前没有做过的事情,我偶然发现谷歌中的一篇文章(同时搜索与原始问题完全不同的内容) ):

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

阅读部分( Ad-hoc cookie管理),这是我的实现(使用我创建的测试服务来模拟您的问题)。你可以在我从标题字符串中重新组装cookie的部分做更多的健全/错误检查......

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

        } 

答案 1 :(得分:1)

所以我花了一些时间来挖掘,搜索,搞乱MessageBehavior和web.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();
}