为什么Silverlight没有为我的自定义ServiceModel.ClientBase <tchannel>频道的行为调用AfterReceiveReply?</tchannel>

时间:2011-02-05 02:14:53

标签: .net silverlight wcf

我有对第三方API的服务引用。我使用自定义ChannelFactory类来为此API构建通道(System.ServiceModel.ClientBase类型的[WCF])。

我有一个自定义行为类(在下面定义),我附加到此通道端点,以便处理从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.

无论REAL错误如何,我都会看到上述错误。在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;

1 个答案:

答案 0 :(得分:5)

不知道这有助于/使用某些东西。

默认情况下,silverlight通过浏览器执行HTTP请求(包括SOAP / REST)。 通过这些调用,所有HTTP / HTTPS请求都将由silverlight-client网络堆栈处理。

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