WCF 到 BizTalk( 传递类型化数据集)
本文解释了如何使用 wsHTTPBinding/basicHTTPBinding 将保存在类型化数据集中的大量数据从 WCF 服务发送到 BizTalk,从而使解决方案能够利用 Biztalk Mapper 将 WCF 消息转换为目标架构。
引言
本文详细介绍了一种简单而强大的方法,可将关系类型化数据集中存储的数据从 WCF 服务传输到 BizTalk Server,从而使开发人员有机会使用 BizTalk Mapper 轻松地将 WCF 响应消息转换为最终目标消息。
背景
我目前正在从事一个主要侧重于解析和处理 HL7 消息的集成项目。是的,你没看错,“HL7”,这意味着我们需要处理一条消息中的大量元素。
现在,对于其中一种 HL7 消息类型 (VXQ),我必须使用 BizTalk Server 实现解决方案的请求-响应模型,以 HL7 适配器作为我的解析和转换引擎,并使用 WCF 作为我的 SOA,包括与 SQL Server 交互以检索 VXQ 消息中请求的数据的业务逻辑和数据层。
简单来说,VXQ 请求患者及其在我们 SQL Server 数据库中的完全关系表中保存的分层数据。
要遵循的步骤鸟瞰图
- 创建类型化数据集,复制数据存储中的数据关系(在本文中,它是 SQL Server)。
- 创建一个存储过程,该存储过程将返回多个结果集,对应于构建出站消息所需的所有表。
- 使用您首选的方法或传统的 ADO.NET 方法填充数据集,即
DataAdapter.Fill
将填充存储过程返回的所有表。 - 使用 XSDObjectGenerator.exe 为类型化数据集创建可序列化的类,以便它可以用作 WCF 部分的
DataContract
。 - 创建 WCF 部分并指定操作合同和数据合同(使用第 4 步创建的可序列化类)。
- 将数据集转换为可以发送到 BizTalk 的可序列化 XML 对象。
- 发布 WCF 服务并在 BizTalk Server 编排中使用请求-响应端口进行消耗。
使用代码
- 创建类型化数据集 (HL7dataset.xsd) 并定义数据关系:我们可以通过简单地将感兴趣的表从服务器资源管理器拖放到 Visual Studio 中来完成此操作,或在 Visual Studio 中创建它们。请参见下面的屏幕截图
- 创建存储过程以返回多个数据集:这非常简单,您可以在 CodeProject 上找到很多关于此的文章。
- 使用 DataAdapter.Fill 填充数据集:在这里,我们必须使用基于表索引的数据填充数据集,数据源为 SQL Server。请参阅下面的代码。
- 使用 XSDObject 生成器,创建类型化数据集的可序列化类:您可以从此处下载 XSDObjectGenerator。
- 创建 WCF 部分并指定操作合同和数据合同(使用第 4 步创建的可序列化类):使用
[XmlSerializerFormat]
属性为操作创建 XML 可序列化的 WCF 服务。 - 将 DataSet 转换为可序列化的 XML 对象:这是最棘手的部分。在这里,我们将数据集转换为
MemoryStream
,然后将其反序列化为将发送到 BizTalk 的消息。 - 发布 WCF 服务并在 BizTalk Server 编排中使用请求-响应端口进行消耗:现在 WCF 服务已准备就绪,请发布它,并在 BizTalk 项目中添加对 WCF 服务的引用:“右键单击 BizTalk 项目 -> 添加 -> 添加生成项 -> 消耗 WCF 服务”。
请确保启用“嵌套关系”复选框。否则,代码生成 (XSDobjectGen) 将无法为您创建分层类。
scmd.Connection = new SqlConnection(@"Data Source="[ServerName]";Initial " +
@"Catalog=[DatabaseName];Persist Security " +
@"Info=True;User ID=User;Password=welcome");
SqlDataAdapter sadapter = new SqlDataAdapter(scmd);
sadapter.TableMappings.Add("Table", "HL7Patients");
sadapter.TableMappings.Add("Table1", "HL7Contacts");
sadapter.Fill(objHL7dataset);
请注意,我们必须使用表映射来填充类型化数据集。它不会根据表名自动加载;因此,我们需要使用表索引并确保存储过程中的顺序也与此对应。
使用以下命令在 VS 命令提示符下创建可序列化类
[Directory]\XSDObjectGenerator>XSDObjectGen.exe HL7dataset.xsd
/l:cs /n:"MyProject.HL7Services" /f:HL7dataset.cs
[ServiceContract]
public interface IVXQService {
[OperationContract]
[XmlSerializerFormat]
MyProject.HL7Services.HL7DataSet ProcessVXQ(InboundMsg objVXQ);
}
注意:“上面代码中看到的 HL7DataSet
不是类型化数据集,而是第 4 步创建的 XML 可序列化类。为避免类名及其成员之间的冲突,请确保使用不同的命名空间,但类名保持不变。否则,我们将无法将类型化数据集转换为 XML 可序列化类并将其发送到 BizTalk。
MemoryStream stream = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.UTF8);
writer.WriteStartDocument();
ds.WriteXml(writer); stream.Seek(0, SeekOrigin.Begin);
using (StreamReader str = new StreamReader(stream))
{
XmlSerializer xs1 =
new XmlSerializer(typeof(MyProject.HL7Services.HL7DataSet));
MyProject.HL7Services.HL7DataSet Result =
(MyProject.HL7Services.HL7DataSet)xs1.Deserialize(str);
}
向导创建并添加 WCF 引用的所有构件后,我们将在名为您的 WCF 服务(VXQService)的编排中获得一个多部分消息,一个用于请求,一个用于响应。我们可以使用转换形状或消息分配形状在响应消息中实现我们的逻辑。
注意:我们需要使用 BizTalk 管理控制台导入上述步骤创建的自定义绑定文件,这将自动在 BizTalk 应用程序中创建请求-响应发送端口。
关注点
- 将类型化数据集转换为可传输到 BizTalk 的 XML 可序列化对象。
- 增加 WCF 客户端(BizTalk Server 发送端口)的“
maxReceivedMessageSize="365536"
”属性,以接受大于默认值的 XML 消息。 - 它应该适用于所有类型的 WCF 绑定。
- 文章中已清楚解释了步骤。如果有人需要示例代码,请告诉我,我将根据需求上传。
历史
草稿版本。