2013-08-23 14 views
12

Quando si aggiungono WebService riferimento a un servizio ASMX su un progetto .NET 2.0 per esempio,Dove posso impostare CookieContainer su un servizio di riferimento?

var objService = new NameSpace.groupservices(); 

esiste,

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

Quando si aggiunge ServiceReference a un servizio ASMX su un progetto di .NET 4.0 per esempio,

var objService = new NameSpace.groupservicesSoapClient(); 

non c'è alcuna proprietà CookieContainer per objService

Una domanda simile è stata richiesta here senza soluzione positiva.

Qualcuno potrebbe per favore guidare dove trovare la proprietà?

+1

@marc_s: anche per un servizio ASMX, si dovrebbe usare "Add Service Reference". –

risposta

-1

trovato la soluzione qui:

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

Si scopre ho bisogno di un punto di riferimento web invece di un riferimento al servizio

+0

Uh, no, non lo fai. Perché pensi di farlo? –

+0

Concordato, i riferimenti Web sono solo la vecchia iterazione. Usa la risposta di @Markus 'sopra, invece, –

8

A differenza di servizi Web ASMX che sono legate al trasporto HTTP, WCF consente di utilizzare vari protocolli di trasporto. Pertanto, non tutte le opzioni specifiche del protocollo (come i cookie per il trasporto HTTP) sono disponibili in un riferimento al servizio WCF.

È tuttavia possibile aggiungere un'ispettore messaggi che ispeziona i messaggi inviati tra client e server. Questo article descrive un modo per inviare cookie al server.

Ho esteso l'esempio per utilizzare un CookieContainer. Inoltre, il codice seguente mostra come valutare l'intestazione Set-Cookie inviata dal server per aggiungere i nuovi cookie al contenitore. Si noti che l'esempio mostra uno schema di base, ma potrebbe richiedere un'estensione o un po 'di convalida. Tuttavia, in un semplice scenario ha funzionato.

Il seguente frammento mostra un metodo di test di un servizio WCF che è ospitato su IIS e integrato nel framework ASP.NET. Si riprende in sostanza i cookie inviati al server in una stringa e aggiunge due nuovi:

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

Il seguente programma di test crea un CookieContainer per i biscotti, aggiunge un cookie demo e registra un nuovo comportamento per il punto finale del servizio:

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

il comportamento ha lo scopo di aggiungere un ispettore messaggio personalizzato e consegna il 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) { } 
} 

il messaggio in spector aggiunge entrambi i cookie quando una richiesta viene inviata al server nel metodo BeforeSendRequest e recupera i cookie che dovrebbero essere aggiornati nel metodo AfterReceiveReply. Si noti che il correlationState restituito da BeforeSendRequest viene utilizzata per recuperare l'Uri nel 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); 
    } 
} 
8

aprire il file app.config e aggiungere AllowCookies = "true" alla rilegatura.

Qualcosa di simile a questo:

<binding allowCookies="true" /> 
+0

Dato che la risposta migliore, vincitrice di taglie, è così complicata, sembra improbabile che questa sia la risposta, ma almeno con l'API di eTapestry, che richiede i cookie per funzionare, questo è tutto ciò che serve . –

+0

Wow ... vecchia risposta ma perfetta. La semplicità vince sulla folle complessità. Sto lavorando con un'API SOAP (InsideSales) che richiede un accesso che imposta un cookie di sessione per tutte le chiamate future. Questo è tutto ciò di cui avevo bisogno. –