16

たとえば、.NET 2.0 プロジェクトの ASMX サービスに WebService 参照を追加すると、

var objService = new NameSpace.groupservices();

が存在します、

objService.CookieContainer = new System.Net.CookieContainer();

たとえば、.NET 4.0 プロジェクトの ASMX サービスに ServiceReference を追加すると、

var objService = new NameSpace.groupservicesSoapClient();

objService の CookieContainer プロパティはありません

同様の質問がここで尋ねられましたが、肯定的な解決策はありません。

誰かがプロパティを見つける場所を案内してもらえますか?

4

3 に答える 3

16

HTTP トランスポートに関連付けられている ASMX Web サービスとは対照的に、WCF ではさまざまなトランスポート プロトコルを使用できます。したがって、すべてのプロトコル固有のオプション (HTTP トランスポートの Cookie など) が WCF サービス参照で使用できるわけではありません。

ただし、クライアントとサーバー間で送信されるメッセージを検査するメッセージ インスペクターを追加することはできます。この記事では、Cookie をサーバーに送信する方法について説明します。

CookieContainer を使用するようにサンプルを拡張しました。また、次のコードはSet-Cookie、サーバーから送信されたヘッダーを評価して、新しい Cookie をコンテナーに追加する方法を示しています。サンプルは基本的な概要を示していますが、拡張またはさらに検証が必要な場合があることに注意してください。ただし、単純なシナリオでは機能しました。

次のスニペットは、IIS でホストされ、ASP.NET フレームワークに統合されている WCF サービスのテスト メソッドを示しています。基本的に、サーバーに送信された Cookie を文字列でエコーし、2 つの新しい Cookie を追加します。

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;
}

次のテスト プログラムは、Cookie の CookieContainer を作成し、デモ Cookie を追加して、サービスのエンドポイントの新しい動作を登録します。

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) { }
}

メッセージ インスペクタは、リクエストがメソッドでサーバーに送信されるときに Cookie を追加し、BeforeSendRequestメソッドで更新する必要がある Cookie を取得しますAfterReceiveReplycorrelationStateによって返されたBeforeSendRequestは、 で Uri を取得するために使用されることに注意してください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);
    }
}
于 2014-04-23T07:10:45.707 に答える
15

app.configファイルを開き、バインディングにallowCookies="true"を追加します。

このようなもの:

<binding allowCookies="true" />
于 2014-08-08T22:13:45.640 に答える
-1

ここで解決策を見つけました:

http://msdn.microsoft.com/en-us/library/bb628649.aspx

サービス参照ではなく Web 参照が必要であることがわかりました

于 2014-04-23T03:10:29.567 に答える