Reputation: 1038
I'm working on a project where I have to call an API in SOAP web service form and get a response back. When the response comes back, there is a Set-Cookie value I have to pull from the header and pass along in the header Cookie value with subsequent API requests. Initially, I've been building my SOAP document from scratch using XmlWriter
. A teammate of mine turned me on to using a Service Reference which meant that I didn't have to write any of the custom XML (BIG WIN).
My main problem is that I have to get the header value, without that, the API calls won't work. Is there a way to get the response header while still being able to use a Service Reference and all the goodness that comes with it?
Upvotes: 3
Views: 5508
Reputation: 1038
So I spent some more time digging, searching, messing around with MessageBehavior
s and web.config settings, and finally found something that solved what I needed. I marked the answer above as the answer to this question because it's close enough to how i solved my issue, but I think the way I've done it is a bit cleaner and is different enough from the above answer to warrant more than a comment.
From this MSDN article, you can use the OperationContextScope
to inspect the response and add values to the subsequent request.
My code ended up looking like this:
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();
}
Upvotes: 1
Reputation: 600
I spent most of the day trying to figure this one out... I ended up writing a WCF service to simulate setting a cookie and sending it out as part of an OperationContract (although this is bad practice, something I wouldn't do practically as WCF isn't HTTP only).
Initially I thought Message Inspectors would do the trick, however after a few hours of code-iteration I ended up writing a custom WebClient class to "simulate" the service reference, which allowed me to see the Headers in a CookieContainer.
So after trying all these different ideas and writing pages and pages of code, as per most times I try something I haven't done before, I stumbled across an article in google (whilst searching for something completely different to the original problem):
http://megakemp.com/2009/02/06/managing-shared-cookies-in-wcf/
Read the section (Ad-hoc cookie management), here's my implementation (using the test Service I created to simulate your problem). You could probably do more sanity/error checking on the section where I re-assemble the cookies from the header string...
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);
}
}
}
Upvotes: 1