简体   繁体   English

如果输入的必需属性为空节点,则返回WCF捕获错误

[英]WCF Catch faults returned if input has empty node for required property

I've created a WCF service that uses Unity/Unity.WCF/Unity.Interceptors for fault handling. 我已经创建了一个使用Unity / Unity.WCF / Unity.Interceptors进行故障处理的WCF服务。

Now, If I do a SOAP request and do NOT include a required node in the request - the service method executes - I throw an exception and my interceptor makes this into a SOAP fault. 现在,如果我执行SOAP请求,并且未在请求中包含必需的节点-服务方法将执行-我将引发异常,而我的拦截器会将其转变为SOAP错误。

Example: 例:

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

I can step through the service call using the debugger - I throw the exception when validating the request object and my interceptor makes this into a SOAP fault: 我可以使用调试器逐步执行服务调用-验证请求对象时抛出异常,而我的拦截器将其变成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>

Now - our tester provided an empty node for the required parameter like so: 现在-我们的测试人员为所需参数提供了一个空节点,如下所示:

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

And the service returns the following error message: 并且该服务返回以下错误消息:

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

The thing is - this request never reaches my service, so I cannot do anything with this error message. 问题是-此请求永远不会到达我的服务,因此我无法对此错误消息做任何事情。 How can I influence what happens here? 我如何影响这里发生的事情?

This reminds me a bit of modelbinding in MVC - can I influence the binding behavior or so? 这使我想起了MVC中的模型绑定-我可以左右绑定行为吗?

OK, I got it. 好,我知道了。 Here's what you need to do: 这是您需要做的:

  • Read this article: http://msdn.microsoft.com/en-us/magazine/cc163302.aspx 阅读本文: http : //msdn.microsoft.com/zh-cn/magazine/cc163302.aspx
  • Create the operation attribute and place it at the over the method in the service 创建操作属性并将其放置在服务中的over方法中
  • Implment an IOperationBehavior with something like 用类似的东西来表现IOperationBehavior

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

  • Create the formatter that implements IDispatchMessageFormatter and do something like this: 创建实现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); } 

It comes down to being able to apply my custom desialization behevior for the operation. 归结为能够将我的自定义反序列化行为应用于该操作。 That behavior deserializes but with a try catch that wraps the exception in an exception with a Dutch message. 该行为会反序列化,但是会使用try catch将异常包装到带有荷兰语消息的异常中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM