wcf读写cookie

一般来说,web应用的服务端(aspx或mvc的action)调用wcf时,是一个服务与服务的通讯,而不是客户端(浏览器)与服务器的通讯。

这种情况下,如果要在wcf端处理客户端的cookie,就需要做一些额外的开发。

首先,在wcf的web.config里,需要启用

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

之后,wcf的实现类需要加attribute

[AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Required)]

做完上面的两步,在wcf具体的方法里就可以使用HttpContext.Current .Resposne/.Request来读写cookie了。

但是,正如上面所说,这是一个服务器与服务器的通讯,客户端(web应用)并不会自动发送cookie到wcf。所以客户端还得做更多的工作

核心在IClientMessageInspector 这个接口,他有

BeforeSendRequest和AfterReceiveReply两个方法。

我们的目的是在beforeSendRequest时,在请求中加入cookie信息,在AfterReciveReply方法中,从响应中获取要设置的cookie,并真正设置到客户端(浏览器)

public class CookieMessageInspector : IClientMessageInspector
新建一个类,来实现接口

   1: public object BeforeSendRequest(ref Message request,System.ServiceModel.IClientChannel channel)
   2: {
   3:     var cookie = GetCookieValue();
   4:  
   5:     HttpRequestMessageProperty httpRequestMessage;
   6:     object httpRequestMessageObject;
   7:  
   8:     if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
   9:     {
  10:         httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
  11:         if (string.IsNullOrEmpty(httpRequestMessage.Headers["Cookie"]))
  12:         {
  13:             httpRequestMessage.Headers["Cookie"] = cookie;
  14:         }
  15:     }
  16:     else
  17:     {
  18:         httpRequestMessage = new HttpRequestMessageProperty();
  19:         httpRequestMessage.Headers.Add("Cookie", cookie);
  20:         request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
  21:     }
  22:  
  23:     return null;
  24: }

我们需要把cookie值,转化成字符串进行传递,cookie名=cookie值这样的形式,多个cookie用分号(;)分隔。

我们新建的这个类,要如何使用呢,他需要在一个behavior中调用。所以我们还得建立一个behavior

public class CookieBehavior : IEndpointBehavior

实现接口IEndpointBehavior,并且在方法ApplyClientBehavior中加入我们刚才的类

public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint,ClientRuntime behavior)
{
    behavior.MessageInspectors.Add(new CookieMessageInspector());
}

其他需要实现的方法,直接return即可

通过vs添加服务引用,他会自动生成一个代理类。在new这个代理类之后,加入我们新建的behavior

var client = new TestSvc.TestSvcClient();
CookieBehavior b = new CookieBehavior();
client.Endpoint.Behaviors.Add(b);

之后,我们调用方法,就会把cookie信息传递到wcf了。

到目前为止,我们可以解决web向wcf传递当前cookie,wcf可以读取cookie。

下面我们解决在wcf中设置cookie。

同样的原理,在读取的时候,我们是在BeforeSendRequest中实现的,那写入则需要在AfterReceiveReply中实现了。

在wcf中使用

HttpContext.Current.Response.Cookies.Add(new HttpCookie("test123", "123"));

类似这样的代码设置cookie,他在响应的header里会有Set-Cookie,我们只需要处理Set-Cookie里面的内容就可以了。

在写入多个cookie时,与读操作不同,这里是用逗号(,)分隔的,并且默认他会带cookie的path,如果你设置了cookie的domain,过期时间等,他也会传递,并且同一个cookie的若干属性之间是用分号(;)分隔的

   1: public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply,object correlationState)
   2: {
   3:     if (reply.Properties.ContainsKey("httpResponse"))
   4:     {
   5:         HttpResponseMessageProperty httpResponse = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
   6:  
   7:         if (httpResponse != null)
   8:         {
   9:             string cookie = httpResponse.Headers.Get("Set-Cookie");
  10:             if (!string.IsNullOrEmpty(cookie))
  11:             {
  12:                 //解析并设置cookie
  13:             }
  14:         }
  15:     }
  16: }

具体如何解析,就是字符串操作,就不细说了。

以上方式可以实现web应用的服务器端与wcf通讯时,附带客户端(浏览器)的cookie信息,进行读写操作。

但是每次都需要对client进行设置,相对比较麻烦。我们可以通过web.config中的配置来让client自动加入behavior。

同样,我们需要下面这样的一个类

public class CookieBehaviorExtensionElement :BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new CookieBehavior();
    }

    public override Type BehaviorType
    {
        get { return typeof(CookieBehavior); }
    }
}

之后,在web项目的web.config中

<system.serviceModel>

此节点下,首先需要加入

<extensions>
  <behaviorExtensions>
    <add name="CookieBehavior" type="webhost.CookieBehaviorExtensionElement, webhost, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </behaviorExtensions>
</extensions>
注意type是的写法,需要根据自己项目的命名空间来进行修改
之后
<behaviors>
  <endpointBehaviors>
    <behavior name="CookieBehaviorConfig">
      <CookieBehavior />
    </behavior>
  </endpointBehaviors>
</behaviors>
黄色部分,为extensions中我们添加的那条的name
最后
<endpoint address="http://localhost:5351/testSvc.svc" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_ITestSvc" contract="TestSvc.ITestSvc"
        name="BasicHttpBinding_ITestSvc" behaviorConfiguration="CookieBehaviorConfig" />
设置endpoint的behaviorConfiguration为behaviors节中添加的behavior的name
 
如此,我们就可以不用每次new client之后在去设置它的behavior了
原文地址:https://www.cnblogs.com/czcz1024/p/3333138.html