我正在开发一个项目,我必须在SOAP Web服务表单中调用API并获得响应。当响应返回时,我必须从标头中提取Set-Cookie值,并在标头Cookie值中传递随后的API请求。最初,我使用XmlWriter
从头开始构建我的SOAP文档。我的一个队友让我使用服务参考,这意味着我没有必要编写任何自定义XML(BIG WIN)。
我的主要问题是我必须获取标头值,否则API调用将无法正常工作。有没有办法获得响应标题,同时仍然能够使用服务参考及其附带的所有好处?
答案 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();
}