BizTalk Orchestration:响应非类型化 SOAP 错误

发布于 2024-09-27 08:40:52 字数 2419 浏览 8 评论 0原文

我有一个 BizTalk 2009 编排,其请求-响应端口类型已发布为 WCF Basic-HTTP Web 服务。该端口有一个操作,并且该操作具有具有适当架构的请求和响应消息。在此端口上收到请求后,在某些情况下,应向客户端返回错误消息而不是标准响应消息。我很难将正确的故障消息返回给客户端。我希望能够设置 SOAP 错误消息的 faultcodefaultstring 元素。这是我尝试过的:

添加字符串类型的故障消息: 我尝试向操作添加消息类型为字符串的错误消息。在编排中,我构建了一条字符串消息并将其作为响应发送。传送回客户端的错误看起来像这样:

<?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">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;string>This is the error message.&lt;/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>&lt;?xml version="1.0" encoding="utf-8"?>
&lt;string>This is the error message.&lt;/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 的故障消息 我想如果我构造 Fault 元素并发送它,我也许能够说服 BizTalk 返回一条与我期望的错误消息相同的错误消息。因此,我添加了一条类型为 http://schemas.xmlsoap.org/soap/envelope/#Fault 的错误消息,构造了适当的消息并将其作为响应发送。结果与上面相同,只是 faultstring 元素包含一个 CDATA 部分,而不是字符串,其中包含我在其中构造的整个 xml 消息。

所以我现在被困住了;我觉得这在 BizTalk 中应该是一个简单的任务。 MSDN 上的文档,如何从已发布的编排中引发故障异常作为 WCF 服务,没有告诉您“如何”抛出故障异常,除了可以抛出它们并且您需要在配置中设置 includeExceptionDetailInFaults (我已经完成了) )。

有人对如何在 BizTalk 2009 中实现这一点有任何建议吗?

I have a BizTalk 2009 orchestration with a request-response port type that is published as a WCF Basic-HTTP web service. The port has one operation, and that operation has request and response messages with appropriate schemas. After receiving a request on this port, there are a few cases where a fault message should be returned to the client instead of the standard response message. I'm having difficulty getting the correct fault message back to the client. I'd like to be able to set both the faultcode and faultstring elements of the SOAP fault message. Here's what I've tried:

Adding a Fault Message of Type String:
I tried adding a fault message with a message type of string to the operation. Within the orchestration, I constructed a string message and sent it as the response. The fault that was delivered back to the client looked like:

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

This almost works, except the faultstring element contains the xml serialized version of my string instead of the string itself. I also cannot set the faultcode element.

Adding a Fault Message of Type http://schemas.xmlsoap.org/soap/envelope/#Fault
I thought I might be able to convince BizTalk to return a fault message along the lines of what I'd expect if I constructed the Fault element and sent that. So I added a fault message with a type of http://schemas.xmlsoap.org/soap/envelope/#Fault, constructed the appropriate message and sent that as the response. The result was the same as above, except instead of a string, the faultstring element contained a CDATA section with the entire xml message I had constructed inside.

So I'm stuck now; I feel like this should be a simple task in BizTalk. The documentation on MSDN, How to Throw Fault Exceptions from Orchestrations Published as WCF Services, tells you nothing about "how" to throw fault exceptions, except that they can be thrown and that you need to set includeExceptionDetailInFaults in the configuration (which I've already done).

Does anyone have any suggestions on how this could be accomplished in BizTalk 2009?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

栩栩如生 2024-10-04 08:40:52

我通过添加自定义 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>

I solved this exact problem by adding a custom WCF IDispatchMessageInspector where i read the reason text from the serialized message and then return a new System.ServiceModel.FaultException message using the deserialized reason text.

In the BizTalk orchestration i use System.String as the PortType fault message-type.

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);
        }
    }
}

Now the SoapFault will look more like this:

<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>
微凉 2024-10-04 08:40:52

想起我前段时间参加的这个长帖子:
http://social. msdn.microsoft.com/forums/en-US/biztalkr2adapters/thread/f69ec7af-a490-4229-81d4-3d1b41bf9c48/

它们引用了一个可能对您有帮助的 SDK 示例,但它是一个类型化的(不是非类型化的)按您的要求)故障异常。

Reminded of this long thread I participated in a while back:
http://social.msdn.microsoft.com/forums/en-US/biztalkr2adapters/thread/f69ec7af-a490-4229-81d4-3d1b41bf9c48/

They refer to an SDK sample that might help you, but it's a typed (not un-typed as you requested) fault exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文