Dot-Net

為什麼 Silverlight 不為我的自定義 ServiceModel.ClientBase<TChannel> 通道的行為呼叫 AfterReceiveReply?

  • May 13, 2011

我有對第三方 API 的服務引用。我使用自定義 ChannelFactory 類來建構頻道(

$$ WCF $$System.ServiceModel.ClientBase 類型)到此 API。 我有一個自定義行為類(定義如下),我將其附加到此通道端點,以處理從 API 返回的任何異常。在我的普通 .NET 程式碼中,這可以正常工作。然而,在 Silverlight 中,只有在沒有錯誤的情況下才會呼叫 AfterReceiveReply 方法。

在這種情況下,當您嘗試引用 eventArgs: 的結果時,呼叫方法會遇到錯誤'eventArgs.Result' threw an exception of type 'System.Reflection.TargetInvocationException'

內部異常有:InnerException = {System.ServiceModel.CommunicationException: The remote server returned an error: NotFound.

無論真正的錯誤如何,我都會看到上述錯誤。在 Fiddler 中,我可以看到真正的錯誤又回來了。只是通道處理隱藏了一些東西。下面是一個實際錯誤的 SOAP 響應範例。(刪除了一些值。)

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;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"&gt;
 &lt;soapenv:Body&gt;
   &lt;soapenv:Fault&gt;
     &lt;faultcode&gt;&lt;!-- REMOVED REAL CODE --&gt;&lt;/faultcode&gt;
     &lt;faultstring&gt;&lt;!-- REMOVED REAL FAULT --&gt;&lt;/faultstring&gt;
     &lt;detail&gt;
       &lt;!-- REMOVED DETAILS --&gt;
     &lt;/detail&gt;
   &lt;/soapenv:Fault&gt;
 &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;

我確定我還沒有提供足夠的資訊,但我不知道什麼是相關的。在評論中詢問更多資訊。

我該如何調試呢?相同的程式碼在 .NET 中工作,但 Silverlight 不能很好地處理它。

一些相關程式碼如下。

行為:

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

頻道創建

//...
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;

不知道這是否有助於/使用某些東西。

預設情況下,silverlight 通過瀏覽器執行 HTTP 請求(包括 SOAP/REST)。通過這些呼叫,所有 HTTP/HTTPS 請求都將由 silverlight-client 網路堆棧處理。

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

引用自:https://stackoverflow.com/questions/4904702