Biztalk使用WCF Adapter调用Web Service

Biztalk WCF Adapter 提供了Biztalk与其它支持WCF或是Web Service通信支持。这里介绍使用Messaging (非Orachestration)调用Web Service碰到的问题及解决方法。

为Biztalk 应用添加一个WCF Adapter的步骤一般如下:

1. 使用visual studio 创建一个Biztalk Project ,然后Add ->Add Generated Items

Biztalk使用WCF Adapter调用Web Service_第1张图片

选中Consume WCF Service

Biztalk使用WCF Adapter调用Web Service_第2张图片

一般如果Web Service在线的话,使用第一个选项自动获取MEX endoint ,输入Web Service 的URL,Visual Studio 会自动生成该Web Service所需的Schema及Binding文件:

2. 使用biztalk admin console 将生成的binding import 到对应的Biztalk应用中

查看对应的Send Port对应,比如:

Biztalk使用WCF Adapter调用Web Service_第3张图片

这时再配置好对应的Receive Port,就可以来测试这个WCF Adapter了。

上面的Web Service提供了多个方法可以调用,对应到Soap Action Header 对应会有如下定义:

<BTSActionMapping>
< Operation Name=”Operation1″ Action=”Action1″>
< Operation Name=”OperationN” Action=”ActionN”>
< /BTSActionMapping>

Biztalk WCF Adapter 在收到XML消息时,需要根据消息Context 中定义的BTS.Operation 内容然后对照BTSActionMapping 选择合适的方法调用Web Service。

对于Web Service提供的方法多于一个时,Biztalk会报告 InvalidOperationException异常:

The adapter failed to transmit message going to send port “WcfSendPort_EpisysWS_EpisysWSHttpSoap12Endpoint” with URL “http://192.168.247.128:8080/WebServicesFramework/services/EpisysWS.EpisysWSHttpSoap12Endpoint/”. It will be retransmitted after the retry interval specified for this Send Port. Details:”System.InvalidOperationException: An action mapping was defined but BTS.Operation was not found in the message context.
at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.LookupAction(IBaseMessageContext messageContext)
at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.SendRequestMessage(IBaseMessage bizTalkMessage, IRequestChannel channel)
at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.SendMessage(IBaseMessage bizTalkMessage)”.

这是因为对于在接受到的XML文件的Context域没有定义Operation ,Biztalk Adapter无法知道收到的消息需要调用Web Service的那个方法。

一个简单的方法是,修改SOAP Action Header 只含一个方法,此时可以不要BTSActionMapping,只要该方法的Action 部分,如: urn:deleteStore. 如果要调用多个方法,可以为每个方法创建一个WCF Adapter,每个Adapter的Action对应该方法的Action部分。 但此时可能又会碰到另一个问题:对于同一类Adapter,Biztalk 只允许一个URL,此次可以通过在URL后加?1 ?2 等来规避。

另外一种方法是通过创建一个Custom pipeline ,为XML消息添加Operation 值。

关键代码如下:

public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
 Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream();
 string messageType = OperationPromotionHelper.ReadMessageType(originalStream);
 originalStream.Seek(0, SeekOrigin.Begin);
 
 if(messageType!=null)
 {
 try
 {
 pInMsg.Context.Promote("Operation",
 "http://schemas.microsoft.com/BizTalk/2003/system-properties",
 messageType);
 }
 catch (Exception ex)
 {
 }
 }
 
 return pInMsg;
}
 
...
 public static string ReadMessageType(Stream messageStream)
{
 
 if (messageStream == null)
 {
 throw new ArgumentNullException("messageStream");
 }
 
 XmlReader xmlReader = new XmlTextReader(messageStream);
 
 xmlReader.Read();
 if(xmlReader.IsStartElement())
 {
 return xmlReader.LocalName;
 }
 return string.Empty;
}

因为我们这个Web Service的BTSActionMapping 定义的Operation和XML的根元素同名,所以使用messageType 作为Operation (BTS.Operation)的值。

然后为Receive Pipeline使用这个自定义的Pipeline即可。

最后打开Tracking看看XML消息的Content部分:

可以看到消息成功Promot Operation ,并把它的值定义为message 的类型,对应于Soap Action head 中的 Operation.

 

你可能感兴趣的:(Web,service,action,SOAP,WCF,binding)