応答ヘッダーに「Set-Cookie」属性を追加することで、WCF サービスの発信応答に複数の Cookie を追加することができました。それはうまく機能し、Cookieは1つのCookieがあり、複数のCookieがない場合にのみ、後続のすべてのリクエストで利用できます.以下の実装を参照してください. 応答で更新する保留中の Cookie がある場合、すべての WCF サービス メソッド呼び出しに Cookie を追加するために、IDispatchMessageInspector インターフェイスを実装して応答ヘッダーに Cookie を追加しています。
応答ヘッダーと要求ヘッダーの Cookie 出力のサンプル
1 クッキー: foo=testcookie1; path=/ --> 2 つ以上の Cookie を呼び出す後続のすべてのリクエストで使用可能: foo=testcookie1; パス=/;、foo2=testcookie2; パス=/;、foo3=testcookie3; パス=/; --> --> 後続のすべてのリクエスト呼び出しで最初の Cookie のみが利用可能で、他の 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));
}
}
}