如果输入具有所需属性的空节点,则返回WCF Catch错误

时间:2013-04-23 14:13:13

标签: wcf unity-container wcf-binding wcf-behaviour

我创建了一个使用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中的一些模型绑定 - 我可以影响绑定行为吗?

1 个答案:

答案 0 :(得分: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);
    }
    

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