我正在尝试使用IErrorHandler接口在WCF中实现自定义错误处理。我想将未处理的异常转换为自定义错误,这是我在XSD中获得的结构。
我的代码如下所示:
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
if (!(error is FaultException))
{
var customFault = new MyCustomFault
{
FaultString = "Something gone wrong",
Detail = new DetailType
{
GeneralFault = new GeneralFaultType
{
Errors = new[]
{
new ErrorType
{
Code = "333"
}
}
}
}
};
var faultException = new FaultException<MyCustomFault>(customFault);
var msgFault = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, msgFault, faultException.Action);
}
}
但是这段代码产生输出肥皂消息
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="cs-CZ">The creator of this fault did not specify a Reason.</faultstring>
<detail>
... MyCustomFault goes here...
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
我只能影响故障的细节元素。我想实现,而不是来自namespece“http://schemas.xmlsoap.org/soap/envelope/”的Fault元素将是我的自定义故障对象。这甚至可能吗?我正在使用XmlSerializer。
谢谢你, 米甲
答案 0 :(得分:1)
不,不幸的是,这是不可能的。 WCF服务通过soap fault消息通知客户端错误的唯一方法。因此,WCF服务必须遵循soap规范。
遵循规范,所有故障消息必须具有相同的结构。请参阅规范:SOAP 1.2,查找第5.4.6节“SOAP故障代码”。您可以找到并举例说明(几乎与您提供的相同)以及所有节点的描述。
在SOAP 1.2中引入了Detail节点(请参阅规范:第5.4.5节SOAP详细信息元素)。
提供您的错误合同,您可以在此处以xml形式注入自定义错误(在Detail元素内)。但是其他xml结构是不可更改的。
答案 1 :(得分:0)
如果您需要遵循供应商的规范,您可以选择定义xml序列化,然后生成xmlReader,然后将该读取器传递给消息。我做了类似的事情,所以我可以单独测试一个修复了故障的行为/ messageInspector。
var xtr = new XmlTextReader("CustomSoapFault.xml");
// I'm only allocating 1MB, you could allocate more if needed
var message = Message.CreateMessage(xtr, 1024 * 1024, MessageVersion.Soap11);
CustomSoapFault.xml
的内容
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
... CustomFault goes here...
</s:Fault>
</s:Body>
</s:Envelope>
当.NET使用此方法生成消息时,Message.IsFault
属性将返回true。
另外,请确保更新soap的命名空间和MessageVersion以使它们匹配。