我有一个BizTalk 2009业务流程,其请求响应端口类型作为WCF Basic-HTTP Web服务发布。该端口有一个操作,该操作具有带适当模式的请求和响应消息。在此端口上收到请求后,在某些情况下应将错误消息返回给客户端而不是标准响应消息。我很难将正确的故障消息反馈给客户端。我希望能够设置SOAP错误消息的faultcode
和faultstring
元素。这是我尝试过的:
添加类型字符串的错误消息: 我尝试在操作中添加带有消息类型string的错误消息。在业务流程中,我构造了一个字符串消息并将其作为响应发送。传递回客户端的错误如下:
<?xml version="1.0" encoding="utf-8"?>
<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="en-US"><?xml version="1.0" encoding="utf-8"?>
<string>This is the error message.</string></faultstring>
<detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"/>
<InnerException i:nil="true"/>
<Message><?xml version="1.0" encoding="utf-8"?>
<string>This is the error message.</string></Message>
<StackTrace>at Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkAsyncResult.End() ...</StackTrace>
<Type>Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkNackException</Type>
</ExceptionDetail>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
这几乎可以工作,除了faultstring
元素包含我的字符串的xml序列化版本而不是字符串本身。我也无法设置faultcode
元素。
添加http://schemas.xmlsoap.org/soap/envelope/#Fault
类型的错误消息
我想我可以说服BizTalk按照我期望构建Fault
元素并发送它的方式返回错误消息。所以我添加了一个类型为http://schemas.xmlsoap.org/soap/envelope/#Fault
的错误消息,构造了相应的消息并将其作为响应发送。结果与上面相同,除了字符串之外,faultstring
元素包含CDATA
部分,其中包含我在内部构建的整个xml消息。
所以我现在被困住了;我觉得这应该是BizTalk中的一个简单任务。 MSDN上的文档How to Throw Fault Exceptions from Orchestrations Published as WCF Services没有告诉你如何抛出错误异常,除了它们可以被抛出,你需要在配置中设置includeExceptionDetailInFaults
(我已经完成了) )。
有没有人对如何在BizTalk 2009中实现这一点有任何建议?
答案 0 :(得分:2)
我通过添加自定义WCF IDispatchMessageInspector解决了这个确切的问题,其中我从序列化消息中读取原因文本,然后使用反序列化的原因文本返回新的System.ServiceModel.FaultException消息。
在BizTalk业务流程中,我使用System.String作为PortType故障消息类型。
public class HandleUntypedSoapFault : IDispatchMessageInspector
{
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
if (reply.IsFault)
{
MessageBuffer buffer = reply.CreateBufferedCopy(int.MaxValue);
MessageFault messageFault = MessageFault.CreateFault(buffer.CreateMessage(), int.MaxValue);
if (!messageFault.HasDetail)
{
reply = buffer.CreateMessage();
return;
}
using (XmlReader reader = XmlReader.Create(new StringReader(messageFault.Reason.ToString())))
{
reader.MoveToContent();
string _faultText = reader.ReadElementContentAsString();
}
reply = Message.CreateMessage(
reply.Version,
new FaultException(
_faultText,
new FaultCode("client")).CreateMessageFault(),
null);
}
}
}
现在SoapFault看起来会更像这样:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-US">An untyped SoapFault from my BizTalk orchestration. This text was set in the orchestration.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
答案 1 :(得分:0)
提醒我参加了一段时间的长篇帖: http://social.msdn.microsoft.com/forums/en-US/biztalkr2adapters/thread/f69ec7af-a490-4229-81d4-3d1b41bf9c48/
它们指的是可能对您有帮助的SDK示例,但它是一个类型化的(不是您请求的非类型化)错误异常。