通过在响应标头中添加“Set-Cookie”属性,我设法在 WCF 服务传出响应中添加了多个 cookie。它工作得很好,只有当有一个 cookie 而不是多个 cookie 时,cookie 才可在所有后续请求中使用。请参考我下面的实现。我通过实现 IDispatchMessageInspector 接口将 cookie 添加到响应标头中,以便在响应中更新任何挂起的 cookie 时在所有 WCF 服务方法调用中添加 cookie。
响应标头和请求标头中的 Cookie 输出示例
1 饼干: foo=testcookie1; path=/ --> 在所有后续请求调用中可用 2 个或更多 cookie:foo=testcookie1; 路径=/;, foo2=testcookie2; 路径=/;, foo3=testcookie3; 路径=/; --> --> 仅在所有后续请求调用中可用的第一个 cookie,但在其他请求中不可用
例如:
设置 cookie 后,我的响应标头将类似于Set-Cookie: foo1=testcookie1;,foo2=testcookie2;, foo3=testcookie3; . 如果我发出另一个请求,则请求标头 cookie 仅包含foo1=testcookie1; 但不是这些 cookie foo2=testcookie2; foo3=testcookie3; . 这就是问题所在。如果我在响应标头中设置了多个 cookie,那么在后续请求调用中它总是只使用第一个 cookie。
请帮我解决这个问题。提前感谢您的友好回复。
执行
public class CookieManagerServiceBehaviorAttribute : Attribute, IServiceBehavior
{
#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
return;
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher channelDispatch in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher endpointDispatch in channelDispatch.Endpoints)
{
endpointDispatch.DispatchRuntime.MessageInspectors.Add(CookieManagerMessageInspector.Instance);
}
}
}
public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
return;
}
#endregion
}
public class CookieManagerMessageInspector : IDispatchMessageInspector
{
private static CookieManagerMessageInspector instance;
private CookieManagerMessageInspector() { }
public static CookieManagerMessageInspector Instance
{
get
{
if (instance == null)
{
instance = new CookieManagerMessageInspector();
}
return instance;
}
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
HttpResponseMessageProperty httpResponse;
if (!reply.Properties.ContainsKey(HttpResponseMessageProperty.Name))
{
reply.Properties.Add(HttpResponseMessageProperty.Name, new HttpResponseMessageProperty());
}
httpResponse = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name];
foreach (Cookie cookie in RenderContext.Current.PendingCookies)
{
if (cookie.Expires > DateTime.Now)
httpResponse.Headers.Add(HttpResponseHeader.SetCookie, "{0}={1}; expires={2}".StringFormat(cookie.Name, cookie.Value, DateTime.Now.AddYears(1).ToUniversalTime()) + ";");
else
httpResponse.Headers.Add(HttpResponseHeader.SetCookie, "{0}={1};".StringFormat(cookie.Name, cookie.Value));
}
}
}