2011-02-05 13 views
8

Ho un riferimento di servizio a un'API di terze parti. Uso una classe ChannelFactory personalizzata per creare canali ([WCF] di tipo System.ServiceModel.ClientBase) in questa API.Perché Silverlight non chiama AfterReceiveReply per il mio comportamento personalizzato del canale ServiceModel.ClientBase <TChannel>?

Ho una classe di comportamento personalizzata (definita di seguito) che allego a questo endpoint di canale per gestire eventuali eccezioni che torno dall'API. Nel mio normale codice .NET, questo funziona bene. In Silverlight, tuttavia, il metodo AfterReceiveReply viene chiamato solo se NON c'è stato alcun errore.

In questo caso, il metodo di chiamata rileva un errore quando si tenta di fare riferimento al risultato dell'eventoArgs: 'eventArgs.Result' threw an exception of type 'System.Reflection.TargetInvocationException'.

L'eccezione interna ha: InnerException = {System.ServiceModel.CommunicationException: The remote server returned an error: NotFound.

E vedo l'errore precedente, indipendentemente dal vero errore. In Fiddler, posso vedere il vero errore tornare. C'è solo qualcosa sull'elaborazione del canale che lo nasconde. Di seguito è riportato un esempio della risposta SOAP che presenta l'errore reale. (Alcuni valori sono stati rimossi.)

<?xml version="1.0" encoding="utf-8"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <soapenv:Body> 
    <soapenv:Fault> 
     <faultcode><!-- REMOVED REAL CODE --></faultcode> 
     <faultstring><!-- REMOVED REAL FAULT --></faultstring> 
     <detail> 
     <!-- REMOVED DETAILS --> 
     </detail> 
    </soapenv:Fault> 
    </soapenv:Body> 
</soapenv:Envelope> 

Sono sicuro che non ho ancora fornito informazioni sufficienti su questo, ma non so che cosa tutto è rilevante. Chiedi maggiori informazioni nei commenti.

Come posso eseguire il debug di questo? Lo stesso codice funziona in .NET, ma Silverlight non lo gestisce bene.

Di seguito è riportato un codice pertinente.

Comportamento:

public class ExceptionMapperBehavior : IClientMessageInspector, IEndpointBehavior 
{ 
    public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 
     //this is only called if there is no fault--not helpful! 
     if (reply == null || !reply.IsFault) 
      return; 

     //todo: make the exception pretty 
    } 

    public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    { 
     //this is always called 
     return null; 
    } 
} 

Canale Creazione:

//... 
var constructor = typeof(T).GetConstructor(new Type[] { typeof(Binding), typeof(EndpointAddress) }); 
var ret = (T)constructor.Invoke(new object[] { binding, endpointAddress }); 
ret.Endpoint.Behaviors.Add(new CredentialInserterEndpointBehavior(_authToken)); 
ret.Endpoint.Behaviors.Add(new ExceptionMapperBehavior()); 
return ret; 

risposta

5

Non so se questo aiuta/usa qualcosa.

da Silverlight impostazione predefinita esegue HTTP-Richieste (includere SOAP/REST) ​​attraverso il browser. Con queste chiamate tutte le richieste HTTP/HTTPS saranno gestite dallo stack di rete silverlight-client.

bool httpResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp); 
bool httpsResult = WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp); 
+0

Questo ha funzionato. Grazie mille. – EndangeredMassa

Problemi correlati