1

我创建了一个使用 Unity/Unity.WCF/Unity.Interceptors 进行故障处理的 WCF 服务。

现在,如果我执行 SOAP 请求并且不在请求中包含所需的节点 - 服务方法执行 - 我抛出异常并且我的拦截器将其变成 SOAP 错误。

例子:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v10="http://services.....nl/.../Schemas/v10">
   <soapenv:Header/>
   <soapenv:Body>
      <v10:TheRequestObject>
      </v10:TheRequestObject>
   </soapenv:Body>
</soapenv:Envelope>

我可以使用调试器单步执行服务调用 - 在验证请求对象时抛出异常,并且我的拦截器将其变成 SOAP 错误:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode>s:Client</faultcode>
         <faultstring xml:lang="nl-NL">Error msg</faultstring>
         <detail> ...
         </detail>
      </s:Fault>
   </s:Body>
</s:Envelope>

现在 - 我们的测试人员为所需参数提供了一个空节点,如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v10="http://services.....nl/.../Schemas/v10">
   <soapenv:Header/>
   <soapenv:Body>
      <v10:WagenlijstRequest>
         <v10:RequiredInteger></v10:RequiredInteger>
      </v10:WagenlijstRequest>
   </soapenv:Body>
</soapenv:Envelope>

并且该服务返回以下错误消息:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
         <faultstring xml:lang="nl-NL">The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the &lt;serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.</faultstring>
      </s:Fault>
   </s:Body>
</s:Envelope>

问题是 - 这个请求永远不会到达我的服务,所以我不能对这个错误消息做任何事情。我如何影响这里发生的事情?

这让我想起了 MVC 中的一些模型绑定——我可以影响绑定行为吗?

4

1 回答 1

0

好,我知道了。这是您需要做的:

  • 阅读这篇文章:http: //msdn.microsoft.com/en-us/magazine/cc163302.aspx
  • 创建操作属性并将其放置在服务中的方法之上
  • 用类似的东西实现 IOperationBehavior

    public void ApplyDispatchBehavior(OperationDescription operationDescription,DispatchOperation dispatchOperation) { dispatchOperation.Formatter = new ExceptionHandlingFormatter(); }

  • 创建实现 IDispatchMessageFormatter 的格式化程序并执行以下操作:

    public void DeserializeRequest(Message message, object[] parameters)
    {
        var serializer = new XmlSerializer(typeof(WagenlijstRequest), "http://services.prorail.nl/OVGS/Schemas/v10");
    
        try
        {
            // Attempts to deserialize the object given the message body
            var result = serializer.Deserialize(message.GetReaderAtBodyContents());
            parameters[0] = new SomeRequest(result as AnotherType);
        }
        catch (Exception e)
        {
            // In case of an exception - wraps the exception in a Dutch one + logs it
            var exception = new RequestDeserializationException(e);
            this.log.Fatal(string.Format("Error while deserializing the following request:\r\n{0}\r\nException:\r\n{1}", message, exception), exception);
            throw new SomeFaultType(exception).AsFaultException();
        }
    }
    
    public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
    {
        return Message.CreateMessage(messageVersion, string.Empty, result);
    }
    

归结为能够将我的自定义反序列化行为应用于操作。该行为反序列化,但使用 try catch 将异常包装在带有荷兰语消息的异常中。

于 2013-05-01T10:22:58.367 回答