.NET WCF故障产生不正确的SOAP 1.1错误code值不正确、故障、错误、NET

2023-09-03 00:10:13 作者:骑鲨鱼过大海的女汉子

我用用的FaultException和FaultException异常&LT试验; T>确定在我们应用的最佳使用模式。我们需要支持周转基金以及非WCF服务的消费者/客户,包括SOAP 1.1和SOAP 1.2客户端。

I am experimenting with using the FaultException and FaultException<T> to determine the best usage pattern in our applications. We need to support WCF as well as non-WCF service consumers/clients, including SOAP 1.1 and SOAP 1.2 clients.

FYI:使用FaultExceptions与结果的wsHttpBinding在SOAP 1.2语义,而使用FaultExceptions与basicHttpBinding的结果SOAP 1.1语义。

FYI: using FaultExceptions with wsHttpBinding results in SOAP 1.2 semantics whereas using FaultExceptions with basicHttpBinding results in SOAP 1.1 semantics.

我使用下面的code抛出的FaultException&LT; FaultDetails&GT;

I am using the following code to throw a FaultException<FaultDetails>:

  throw new FaultException<FaultDetails>(
      new FaultDetails("Throwing FaultException<FaultDetails>."),
      new FaultReason("Testing fault exceptions."),
      FaultCode.CreateSenderFaultCode(new FaultCode("MySubFaultCode"))
      );

该FaultDetails类只是包含字符串消息财产,你可以看到下面一个简单的测试类。

The FaultDetails class is just a simple test class that contains a string "Message" property as you can see below.

在使用WsHttpBinding的回应是:

When using wsHttpBinding the response is:

<?xml version="1.0" encoding="utf-16"?>
<Fault xmlns="http://www.w3.org/2003/05/soap-envelope">
<Code>
  <Value>Sender</Value>
  <Subcode>
    <Value>MySubFaultCode</Value>
  </Subcode>
</Code>
<Reason>
  <Text xml:lang="en-US">Testing fault exceptions.</Text>
</Reason>
<Detail>
  <FaultDetails xmlns="http://schemas.datacontract.org/2004/07/ClassLibrary" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Message>Throwing FaultException&lt;FaultDetails&gt;.</Message>
  </FaultDetails>
</Detail>

这根据SOAP 1.2规范看起来正确。主/根code是发件人,其中有MySubFault code的一个子code。如果服务消费者/客户端使用WCF中的FaultException在客户端还模仿相同的结构,用的FaultException。code.Name是发件人和FaultException异常。code.Sub code.Name被MySubFault code。

This looks right according to the SOAP 1.2 specs. The main/root "Code" is "Sender", which has a "Subcode" of "MySubFaultCode". If the service consumer/client is using WCF the FaultException on the client side also mimics the same structure, with the faultException.Code.Name being "Sender" and faultException.Code.SubCode.Name being "MySubFaultCode".

在使用basicHttpBinding的回应是:

When using basicHttpBinding the response is:

<?xml version="1.0" encoding="utf-16"?>
<s:Fault xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <faultcode>s:MySubFaultCode</faultcode>
  <faultstring xml:lang="en-US">Testing fault exceptions.</faultstring>
  <detail>
    <FaultDetails xmlns="http://schemas.datacontract.org/2004/07/ClassLibrary" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <Message>Throwing FaultException&lt;FaultDetails&gt;.</Message>
    </FaultDetails>
  </detail>
</s:Fault>

这看起来不正确的。纵观SOAP 1.1规范,我期待看到故障code有值:当我使用故障code.CreateSenderFault codeS Client.MySubFault code (新故障code(MySubFault code))。另外一个WCF客户端得到一个不正确的结构。该FaultException异常。code.Name是MySubFault code而不是被发件人,以及FaultException异常。code.Sub code为null,而不是FaultException异常。code.Sub code.Name是MySubFault code。此外,FaultException异常。code.IsSenderFault是假的。

This does not look right. Looking at the SOAP 1.1 specs, I was expecting to see the "faultcode" to have a value of "s:Client.MySubFaultCode" when I use FaultCode.CreateSenderFaultCode(new FaultCode("MySubFaultCode")). Also a WCF client gets an incorrect structure. The faultException.Code.Name is "MySubFaultCode" instead of being "Sender", and the faultException.Code.SubCode is null instead of faultException.Code.SubCode.Name being "MySubFaultCode". Also, the faultException.Code.IsSenderFault is false.

类似的问题,当使用故障code.CreateReceiverFault code(新故障code(MySubFault code)):

Similar problem when using FaultCode.CreateReceiverFaultCode(new FaultCode("MySubFaultCode")):

工作如预期的SOAP 1.2 生成:而不是s MySubFault code,S:Server.MySubFault code和FaultException异常code.IsReceiverFault是假的SOAP 1.1

这个项目也张贴由别人在 HTTP:/ /forums.microsoft.com/MSDN/ShowPost.aspx?PostID=669420&SiteID=1 于2006年,没有人回答了这个问题。我觉得很难相信,没有人遇到了这一点,但是。

This item was also posted by someone else on http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=669420&SiteID=1 in 2006 and no one has answered it. I find it very hard to believe that no one has run into this, yet.

下面是别人有类似的问题:的http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3883110&SiteID=1&mode=1

Here is someone else having a similar problem: http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3883110&SiteID=1&mode=1

微软连接错误:的https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=367963

说明:的 http://blogs.msdn.com/drnick/archive/2006/12/19/creating-faults-part-3.aspx

我是不是做错了什么,或者这是一个真正的错误,在WCF?

Am I doing something wrong or is this truly a bug in WCF?

推荐答案

这是我目前的解决方法:

This is my current workaround:

	/// <summary>
	/// Replacement for the static methods on FaultCode to generate Sender and Receiver fault codes due
	/// to what seems like bugs in the implementation for basicHttpBinding (SOAP 1.1). wsHttpBinding 
	/// (SOAP 1.2) seems to work just fine.
	/// 
	/// The subCode parameter for FaultCode.CreateReceiverFaultCode and FaultCode.CreateSenderFaultCode
	/// seem to take over the main 'faultcode' value in the SOAP 1.1 response, whereas in SOAP 1.2 the
	/// subCode is correctly put under the 'Code->SubCode->Value' value in the XML response.
	/// 
	/// This workaround is to create the FaultCode with Sender/Receiver (SOAP 1.2 terms, but gets
	/// translated by WCF depending on the binding) and an agnostic namespace found by using reflector
	/// on the FaultCode class. When that NS is passed in WCF seems to be able to generate the proper
	/// response with SOAP 1.1 (Client/Server) and SOAP 1.2 (Sender/Receiver) fault codes automatically.
	/// 
	/// This means that it is not possible to create a FaultCode that works in both bindings with
	/// subcodes.
	/// </summary>
	/// <remarks>
	/// See http://stackoverflow.com/questions/65008/net-wcf-faults-generating-incorrect-soap-11-faultcode-values
	/// for more details.
	/// </remarks>
	public static class FaultCodeFactory
	{
		private const string _ns = "http://schemas.microsoft.com/ws/2005/05/envelope/none";

		/// <summary>
		/// Creates a sender fault code.
		/// </summary>
		/// <returns>A FaultCode object.</returns>
		/// <remarks>Does not support subcodes due to a WCF bug.</remarks>
		public static FaultCode CreateSenderFaultCode()
		{
			return new FaultCode("Sender", _ns);
		}

		/// <summary>
		/// Creates a receiver fault code.
		/// </summary>
		/// <returns>A FaultCode object.</returns>
		/// <remarks>Does not support subcodes due to a WCF bug.</remarks>
		public static FaultCode CreateReceiverFaultCode()
		{
			return new FaultCode("Receiver", _ns);
		}
	}

可悲的是,我不明白的方式使用子codeS没有打破SOAP 1.1或1.2的客户端。

Sadly I don't see a way to use subcodes without breaking either SOAP 1.1 or 1.2 clients.

如果您使用code.Sub code语法,您可以创建SOAP 1.1兼容的故障code值,但它打破SOAP 1.2。

If you use the Code.SubCode syntax, you can create SOAP 1.1 compatible faultcode values but it breaks SOAP 1.2.

如果您使用.NET适当子code支持(通过静态故障code方法或重载之一),它打破SOAP 1.1,但工作在SOAP 1.2。

If you use the proper subcode support in .NET (either via the static FaultCode methods or one of the overloads) it breaks SOAP 1.1 but works in SOAP 1.2.