のWeb参照を必要としますさまざまなトランスポートプロトコルを使用できます。したがって、WCFサービス参照では、すべてのプロトコル固有のオプション(HTTPトランスポートのCookieなど)が使用できるわけではありません。
ただし、クライアントとサーバーの間で送信されるメッセージを検査するメッセージインスペクタを追加できます。このarticleには、サーバーにCookieを送信する方法が記載されています。
CookieContainerを使用するようにサンプルを拡張しました。また、次のコードは、新しいCookieをコンテナに追加するためにサーバーによって送信されたSet-Cookie
ヘッダーを評価する方法を示しています。サンプルには基本的な概要が示されていますが、拡張が必要な場合や、検証が必要な場合があります。しかし、単純なシナリオではうまくいきました。
次のスニペットは、IISでホストされ、ASP.NETフレームワークに統合されたWCFサービスのテスト方法を示しています。これは、基本的には、文字列内のサーバーに送信されたクッキーをエコーし、二つの新しいものが追加されます。
public string GetData(int value)
{
var reply = string.Join(", ",
from x in HttpContext.Current.Request.Cookies.AllKeys
select x + "=" + HttpContext.Current.Request.Cookies[x].Value);
HttpContext.Current.Response.Cookies.Add(new HttpCookie("Test", "Test123"));
HttpContext.Current.Response.Cookies.Add(new HttpCookie("Test2", "Test1234"));
return reply;
}
次のテストプログラムは、クッキーのためにCookieContainerを作成するデモクッキーを追加し、終点のための新しい動作を登録しますサービス:
class Program
{
static void Main(string[] args)
{
var cookieCont = new CookieContainer();
using(var svc = new TestServiceReference.TestServiceClient())
{
cookieCont.Add(svc.Endpoint.Address.Uri, new Cookie("TestClientCookie", "Cookie Value 123"));
var behave = new CookieBehavior(cookieCont);
svc.Endpoint.EndpointBehaviors.Add(behave);
var data = svc.GetData(123);
Console.WriteLine(data);
Console.WriteLine("---");
foreach (Cookie x in cookieCont.GetCookies(svc.Endpoint.Address.Uri))
Console.WriteLine(x.Name + "=" + x.Value);
}
Console.ReadLine();
}
}
挙動はCookieContainer上カスタムメッセージインスペクタ及び取り扱いを添加する目的を果たす:
public class CookieBehavior : IEndpointBehavior
{
private CookieContainer cookieCont;
public CookieBehavior(CookieContainer cookieCont)
{
this.cookieCont = cookieCont;
}
public void AddBindingParameters(ServiceEndpoint serviceEndpoint,
System.ServiceModel.Channels
.BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint,
System.ServiceModel.Dispatcher.ClientRuntime behavior)
{
behavior.MessageInspectors.Add(new CookieMessageInspector(cookieCont));
}
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint,
System.ServiceModel.Dispatcher
.EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint serviceEndpoint) { }
}
メッセージでspectorは、BeforeSendRequest
メソッドでリクエストがサーバーに送信されたときにクッキーを追加し、AfterReceiveReply
メソッドで更新する必要があるCookieを取得します。 BeforeSendRequest
によって返さcorrelationState
がAfterReceiveReply
でウリを取得するために使用されることに注意してください:
public class CookieMessageInspector : IClientMessageInspector
{
private CookieContainer cookieCont;
public CookieMessageInspector(CookieContainer cookieCont)
{
this.cookieCont = cookieCont;
}
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply,
object correlationState)
{
object obj;
if (reply.Properties.TryGetValue(HttpResponseMessageProperty.Name, out obj))
{
HttpResponseMessageProperty httpResponseMsg = obj as HttpResponseMessageProperty;
if (!string.IsNullOrEmpty(httpResponseMsg.Headers["Set-Cookie"]))
{
cookieCont.SetCookies((Uri)correlationState, httpResponseMsg.Headers["Set-Cookie"]);
}
}
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request,
System.ServiceModel.IClientChannel channel)
{
object obj;
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out obj))
{
HttpRequestMessageProperty httpRequestMsg = obj as HttpRequestMessageProperty;
SetRequestCookies(channel, httpRequestMsg);
}
else
{
var httpRequestMsg = new HttpRequestMessageProperty();
SetRequestCookies(channel, httpRequestMsg);
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMsg);
}
return channel.RemoteAddress.Uri;
}
private void SetRequestCookies(System.ServiceModel.IClientChannel channel, HttpRequestMessageProperty httpRequestMessage)
{
httpRequestMessage.Headers["Cookie"] = cookieCont.GetCookieHeader(channel.RemoteAddress.Uri);
}
}
@marc_s:でもASMXサービスのために、彼は "サービス参照の追加" を使用してする必要があります。 –