C# Cookies在设置后但在请求之前被剥离

C# Cookies在设置后但在请求之前被剥离,c#,asp.net,web-services,wcf,cookies,C#,Asp.net,Web Services,Wcf,Cookies,我遇到了一个问题,我可以从一个web服务的登录调用中检索两个cookie,但这两个cookie都是从对不同web服务的任何请求中剥离出来的 一点背景:我有一个Windows服务(.NET 4.5),需要将数据发送到另一个公司的web服务界面。它们的接口由两个不同的独立web服务组成。要连接,我必须从他们的一个服务调用登录web方法;我将其称为服务A。log-in方法返回一个长值,该值由日期时间标记以及两个cookie组成:会话cookie和授权cookie。每个请求中都必须包含这两个cookie

我遇到了一个问题,我可以从一个web服务的登录调用中检索两个cookie,但这两个cookie都是从对不同web服务的任何请求中剥离出来的

一点背景:我有一个Windows服务(.NET 4.5),需要将数据发送到另一个公司的web服务界面。它们的接口由两个不同的独立web服务组成。要连接,我必须从他们的一个服务调用登录web方法;我将其称为服务A。log-in方法返回一个长值,该值由日期时间标记以及两个cookie组成:会话cookie和授权cookie。每个请求中都必须包含这两个cookie

如果我调用服务A中的任何方法,请求中都会包含两个cookie。使用Fiddler,我已经能够验证这一点。但是,如果我尝试调用服务B中的方法,则在请求调用之前,两个cookie都会从请求调用中剥离

以下是我当前使用的类和代码:

CookieBehavior类

public sealed class CookieBehavior : IContractBehavior, IEndpointBehavior, IClientMessageInspector
    {
        #region Private fields
        public CookieContainer cookieContainer = new CookieContainer();
        #endregion

        #region Public constructors
        public CookieBehavior()
            : this(true)
        {
        }

        public CookieBehavior(Boolean shared)
        {
            this.Shared = shared;
        }
        #endregion

        #region Public properties
        public Boolean Shared
        {
            get;
            private set;
        }
        #endregion

        #region Private methods
        private void getCookies(HttpResponseMessageProperty prop, CookieContainer cookieContainer)
        {
            if (prop != null)
            {
                String header = prop.Headers[HttpResponseHeader.SetCookie];

                if (header != null)
                {
                    String[] cookies = header.Split(',');
                    var cc = new CookieCollection();
                    foreach (string cookie in cookies)
                    {
                        if (cookie.Contains(";"))
                        {
                            cc.Add(new Cookie(cookie.Substring(0, cookie.IndexOf("=")),
                                cookie.Substring(cookie.IndexOf("=") + 1, cookie.IndexOf(";") - (cookie.IndexOf("=") + 1))));
                        }
                        else
                        {
                            cc.Add(new Cookie(cookie.Substring(0, cookie.IndexOf("=")), cookie.Substring(cookie.IndexOf("=") + 1)));
                        }
                    }
                    cookieContainer.Add(new Uri(@"http://tempuri.org"), cc);
                }
            }
        }

        private void setCookies(HttpRequestMessageProperty prop, CookieContainer cookieContainer)
        {
            if (prop != null)
            {
                prop.Headers.Add(HttpRequestHeader.Cookie, cookieContainer.GetCookieHeader(new Uri(@"http://tempuri.org")));
            }
        }
        #endregion

        #region IClientMessageInspector Members

        void IClientMessageInspector.AfterReceiveReply(ref Message reply, Object correlationState)
        {
            if (((this.Shared == true) ? CookieContext.Current.cookieContainer : this.cookieContainer).Count == 0)
            {
                HttpResponseMessageProperty prop = reply.Properties[HttpResponseMessageProperty.Name.ToString()] as HttpResponseMessageProperty;
                this.getCookies(prop, (this.Shared == true) ? CookieContext.Current.cookieContainer : this.cookieContainer);
            }
        }

        Object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            HttpRequestMessageProperty prop = null;
            if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name.ToString()))
                prop = request.Properties[HttpRequestMessageProperty.Name.ToString()] as HttpRequestMessageProperty;
            else
                prop = new HttpRequestMessageProperty();
            this.setCookies(prop, (this.Shared == true) ? CookieContext.Current.cookieContainer : this.cookieContainer);
            return (null);
        }
        #endregion

        #region IEndpointBehavior Members

        void IEndpointBehavior.AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
        {
            behavior.MessageInspectors.Add(this);
        }

        void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
        {
        }

        void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint)
        {
        }

        #endregion

        #region IContractBehavior Members

        void IContractBehavior.AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        void IContractBehavior.ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            endpoint.Behaviors.Add(this);
        }

        void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
        }

        void IContractBehavior.Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
        }

        #endregion
    }
public class CookieContext : IDisposable
    {
        #region Internal fields
        internal CookieContainer cookieContainer = new CookieContainer();
        #endregion

        #region Private static fields
        [ThreadStatic]
        private static CookieContext current = null;
        #endregion

        #region Public static constructor
        public CookieContext()
        {
            current = this;
        }
        #endregion

        #region Public static properties
        public static CookieContext Current
        {
            get
            {
                return (current);
            }
        }
        #endregion

        #region IDisposable Members

        void IDisposable.Dispose()
        {
            this.cookieContainer.SetCookies(new Uri(@"http://tempuri.org"), String.Empty);
            this.cookieContainer = null;
            current = null;
        }

        #endregion
    }
CookieContext类

public sealed class CookieBehavior : IContractBehavior, IEndpointBehavior, IClientMessageInspector
    {
        #region Private fields
        public CookieContainer cookieContainer = new CookieContainer();
        #endregion

        #region Public constructors
        public CookieBehavior()
            : this(true)
        {
        }

        public CookieBehavior(Boolean shared)
        {
            this.Shared = shared;
        }
        #endregion

        #region Public properties
        public Boolean Shared
        {
            get;
            private set;
        }
        #endregion

        #region Private methods
        private void getCookies(HttpResponseMessageProperty prop, CookieContainer cookieContainer)
        {
            if (prop != null)
            {
                String header = prop.Headers[HttpResponseHeader.SetCookie];

                if (header != null)
                {
                    String[] cookies = header.Split(',');
                    var cc = new CookieCollection();
                    foreach (string cookie in cookies)
                    {
                        if (cookie.Contains(";"))
                        {
                            cc.Add(new Cookie(cookie.Substring(0, cookie.IndexOf("=")),
                                cookie.Substring(cookie.IndexOf("=") + 1, cookie.IndexOf(";") - (cookie.IndexOf("=") + 1))));
                        }
                        else
                        {
                            cc.Add(new Cookie(cookie.Substring(0, cookie.IndexOf("=")), cookie.Substring(cookie.IndexOf("=") + 1)));
                        }
                    }
                    cookieContainer.Add(new Uri(@"http://tempuri.org"), cc);
                }
            }
        }

        private void setCookies(HttpRequestMessageProperty prop, CookieContainer cookieContainer)
        {
            if (prop != null)
            {
                prop.Headers.Add(HttpRequestHeader.Cookie, cookieContainer.GetCookieHeader(new Uri(@"http://tempuri.org")));
            }
        }
        #endregion

        #region IClientMessageInspector Members

        void IClientMessageInspector.AfterReceiveReply(ref Message reply, Object correlationState)
        {
            if (((this.Shared == true) ? CookieContext.Current.cookieContainer : this.cookieContainer).Count == 0)
            {
                HttpResponseMessageProperty prop = reply.Properties[HttpResponseMessageProperty.Name.ToString()] as HttpResponseMessageProperty;
                this.getCookies(prop, (this.Shared == true) ? CookieContext.Current.cookieContainer : this.cookieContainer);
            }
        }

        Object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            HttpRequestMessageProperty prop = null;
            if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name.ToString()))
                prop = request.Properties[HttpRequestMessageProperty.Name.ToString()] as HttpRequestMessageProperty;
            else
                prop = new HttpRequestMessageProperty();
            this.setCookies(prop, (this.Shared == true) ? CookieContext.Current.cookieContainer : this.cookieContainer);
            return (null);
        }
        #endregion

        #region IEndpointBehavior Members

        void IEndpointBehavior.AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
        {
            behavior.MessageInspectors.Add(this);
        }

        void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
        {
        }

        void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint)
        {
        }

        #endregion

        #region IContractBehavior Members

        void IContractBehavior.AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        void IContractBehavior.ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            endpoint.Behaviors.Add(this);
        }

        void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
        }

        void IContractBehavior.Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
        }

        #endregion
    }
public class CookieContext : IDisposable
    {
        #region Internal fields
        internal CookieContainer cookieContainer = new CookieContainer();
        #endregion

        #region Private static fields
        [ThreadStatic]
        private static CookieContext current = null;
        #endregion

        #region Public static constructor
        public CookieContext()
        {
            current = this;
        }
        #endregion

        #region Public static properties
        public static CookieContext Current
        {
            get
            {
                return (current);
            }
        }
        #endregion

        #region IDisposable Members

        void IDisposable.Dispose()
        {
            this.cookieContainer.SetCookies(new Uri(@"http://tempuri.org"), String.Empty);
            this.cookieContainer = null;
            current = null;
        }

        #endregion
    }
我的代码

ServicePointManager.Expect100Continue = true;
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
                    ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);

                    using (var cookieCtx = new CookieContext())
                    {
                        ServiceA.ServiceASoapClient serviceA_req = new ServiceA.ServiceASoapClient();
                        ServiceB.ServiceBSoapClient serviceB_req = new ServiceB.ServiceBSoapClient();

                        var cookieBhr = new CookieBehavior(true);

                        serviceA_req.Endpoint.EndpointBehaviors.Add(cookieBhr);
                        serviceB_req.Endpoint.EndpointBehaviors.Add(cookieBhr);

                        long? loginTicks = serviceA_req.InterfaceLogin();

                        if (loginTicks.HasValue) 
                        {
                            // Get/Set data for request call

                            serviceB_resp = serviceB_req.SendData(fooBar);
                        }

                    }
调试我的应用程序表明,这两个cookie头都是从请求中正确设置的,但它们在服务B请求之前被剥离

为什么这两个cookie会从第二个请求中被剥离