為什麼 Silverlight 不為我的自定義 ServiceModel.ClientBase<TChannel> 通道的行為呼叫 AfterReceiveReply?
我有對第三方 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 響應範例。(刪除了一些值。)
<?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>我確定我還沒有提供足夠的資訊,但我不知道什麼是相關的。在評論中詢問更多資訊。
我該如何調試呢?相同的程式碼在 .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);