WCF通用FaultException未填充SOAP正文详细信息元素
本文关键字:正文 详细信息 元素 SOAP 填充 通用 FaultException WCF | 更新日期: 2023-09-27 18:28:02
当我尝试抛出FaultException<T>
时,如果我手动生成Message,我会得到正确的SOAP消息。但是,当我从服务器上的方法抛出FaultException<T>
时,我没有得到正确的SOAP消息。SOAP消息的Header/Action值为http://www.w3.org/2005/08/addressing/soap/fault,而我的Body/Fault/Detail元素完全丢失。
请看一下我代码中的重要部分。
服务合同
[ServiceContract(Namespace = "http://namespace.com/fault")]
public interface IFaultService
{
[OperationContract(IsOneWay = false)]
[FaultContract(typeof (MyFault))]
void ThrowFaultException();
}
实施(message_fault和message是手动创建的,仅用于测试)
public class FaultService : IFaultService
{
public void ThrowFaultException()
{
var fault = new MyFault("This is from the service");
var fault_exception = new FaultException<MyFault>
(fault,
"Fault Service Reason",
FaultCode.CreateReceiverFaultCode("FaultCodeName","http://namespace.com/fault"),
"http://namespace.com/fault/IFaultService/ThrowFaultExceptionMyFaultFault");
var message_fault = fault_exception.CreateMessageFault();
var message = Message.CreateMessage(MessageVersion.Soap12WSAddressing10, message_fault,
fault_exception.Action);
throw fault_exception;
}
}
数据合同
[DataContract(Namespace = "http://namespace.com/fault")]
public class MyFault
{
public MyFault(string Message)
{
this.Message = Message;
}
[DataMember]
public string Message { get; set; }
}
web.config system.serviceModel部分
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingNoSecurity">
<security mode="None"/>
</binding>
</wsHttpBinding>
<services>
<service name="FaultService">
<endpoint address="ws"
binding="wsHttpBinding"
bindingConfiguration="wsHttpBindingNoSecurity"
bindingNamespace="http://namespace.com/fault"
contract="IFaultService"
name="ws">
</endpoint>
</service>
</services>
...
</system.serviceModel>
手动生成的SOAP消息
{<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://namespace.com/fault/IFaultService/ThrowFaultExceptionMyFaultFault</a:Action>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Receiver</s:Value>
<s:Subcode>
<s:Value xmlns:a="http://namespace.com/fault">a:FaultCodeName</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-US">Fault Service Reason</s:Text>
</s:Reason>
<s:Detail>
<MyFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://namespace.com/fault">
<Message>This is from the service</Message>
</MyFault>
</s:Detail>
</s:Fault>
</s:Body>
</s:Envelope>}
但实际出现的SOAP是
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
<a:RelatesTo>urn:uuid:a3587103-953a-43f6-9691-951c21de8418</a:RelatesTo>
<ActivityId CorrelationId="23bf0a82-f4ac-4227-85ab-600f6ffe6a6f" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">a0945fa9-f5a3-4958-8682-097a8315f0dc</ActivityId>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-US">Fault Service Reason</s:Text>
</s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
提前谢谢。
好吧,把这个归结为经验。。。
在为依赖注入构建服务的过程中,有一个IErrorHandler
的实现被添加到代码中的服务中。ProvideFault
方法的实现将所有异常和故障转换为返回给客户端的非通用故障。
一旦更正了该实现并刷新了服务引用,一切都按预期进行。