到目前为止介绍的所有组件在处理消息时都起到了一定的作用,因为它们流经 BizTalk Server。 本部分更详细地介绍了这些组件在功能上如何交互,从接收消息开始。 下图显示了接收端口的构成,以及通过接收过程的消息流。
接收端口由一个或多个接收位置和零个或多个映射组成。 映射是可扩展样式表语言转换(XSLT)样式表,用于将 XML 消息从一个结构或格式转换为另一种结构或格式,并且通常用于接收过程中将消息规范化为内部格式。 接收位置控制接收消息的终结点。 接收位置由接收适配器的终结点配置和接收管道组成。
适配器的角色
接收适配器通过读取数据流和创建消息来启动接收消息的过程。 例如,文件适配器看到文件已放置在其配置的位置,并在流中读取该文件。 适配器创建一条消息(Microsoft.BizTalk.Message.Interop.IBaseMessage 接口的实现),向该接口添加一个部分(Microsoft.BizTalk.Message.Interop.IBasePart 接口的实现),并将数据流作为部件内容提供。
此外,适配器还会将与位置、适配器类型及适配器相关的其他内容写入并传递给消息上下文属性。 创建消息及其上下文后,适配器会将消息传递给 Endpoint Manager。 然后,通过已为接收位置配置的接收管道处理消息。 管道处理消息后,可以使用映射将消息转换为所需的格式,然后 Endpoint Manager 使用消息代理发布消息。
管道的角色
虽然它是创建初始消息的适配器,但在接收的消息上发生的大多数处理发生在接收管道中。 管道处理消息内容,以及消息上下文。 消息内容通常在解码、反汇编和验证阶段中进行处理,而可在所有阶段处理消息上下文。 但是,管道不一定对内容或上下文起作用。 例如,默认直通管道未配置任何组件,并且不会对消息内容或上下文执行任何处理。 为简单起见,本文档重点介绍反汇编组件,因为它们通常对消息路由产生最大的影响。
反汇编程序的工作是处理来自适配器的传入消息并将其反汇编成许多消息,并分析消息数据。 当传入消息包含许多较小的消息时,这称为 交换。 平面文件反汇编程序和 XML 反汇编程序都通过使开发人员能够配置有关包装内容的信息(即平面文件反汇编器的标头和尾随架构)和 XML 反汇编程序的信封架构以及(可能重复的)正文内容来处理交换。 此外,这两个反汇编程序将原始消息分析为 XML 内容。 如果不需要 BizTalk Server 中的进一步 XML 处理,自定义反汇编程序不一定将内容分析为 XML。 示例方案可能包括一个简单的路由情况,在该情况下,在特定接收位置输入系统的消息将发送到特定发送端口,且没有映射或其他基于 XML 的处理。
使用消息类型进行路由
路由中使用的最常见消息属性之一是消息类型。 当开发人员创建架构来定义消息的结构时,此架构定义该消息的消息类型。 该类型由架构定义中的根节点和命名空间确定。 例如,如下所示的 XML 文档将具有消息类型 http://tempuri.org/samples/MessageType#Message
<Message xmlns=http://tempuri.org/samples/MessageType>
<SomeOtherElement type="sample"/>
</Message>
若要在路由中使用消息类型,必须将其提升到上下文中。 反汇编程序用于将此值传递到消息上下文中,以及传递到拥有对消息结构最具体了解的管道组件中。 XML 和平面文件反汇编程序在处理消息时提升消息类型,并且任何自定义反汇编程序也应提升此属性以确保正确的路由。
请注意,消息不一定需要具有类型。 如前所述,消息的各个部分可以是任何二进制数据,并且不需要定义其结构的架构。 这种类型的消息部件通常未经太多处理就通过 BizTalk Server,BizTalk Server 本身可能进行少量处理,不过从业务流程中调用的自定义管道组件、适配器或代码可能会与这些部件进行交互。
管道组件(例如适配器)也会将属性写入并提升到消息上下文中。 事实上,管道组件是大多数开发人员用于获取消息上下文中的属性的最常用机制。 开发人员创建架构,并且可以提升架构中的属性。 此信息以注释的形式存储在架构中,然后管道组件可以使用这些注释。 所有内置反汇编程序和汇编程序组件(FlatFile、XML 和 BizTalk Framework)都使用文档架构检索要提升的属性的相关信息。 使用批注中的 XML 路径语言 (XPath) 语句,反汇编程序知道要提升的元素文档中的位置。 在流式传输文档的过程中,反汇编程序会查找与其中一个 XPath 语句匹配的元素,并根据需要将值提升或写入上下文。
还可以编写自定义管道组件,以处理将属性传入接收或发送的消息中的任意数据的上下文中。 为了将属性提升到上下文中并使其可用于路由,这大概是提升值的原因,应创建具有属性定义的属性架构并将其部署到 BizTalk Server。 在定义自定义组件要使用的属性架构之前,应了解不同类型的已升级属性。 在属性架构中定义的提升属性可以有以下两种基类型之一:
Microsoft.XLANGs.BaseTypes.MessageDataPropertyBase
具有 MessageDataPropertyBase 基类型的属性指示此属性的值来自消息的内容。 这是属性架构中定义的属性的默认值,也是最常见的用法。 MessageContextPropertyBase 指示一个属性,该属性旨在成为消息上下文的一部分,但不一定直接来自消息数据。 使用 MessageContextPropertyBase 作为基类型的属性通常由适配器和解包程序传播,并包括常见属性,如消息类型和适配器类型。
请务必了解不同的类型,并在定义属性时适当地使用它们。 当访问业务流程编排中消息的上下文属性时,会带来最显著的影响之一。 如果属性被识别为 MessageDataPropertyBase,协调设计器将检查收到的消息的架构,并确保它定义与之匹配的晋升属性。 如果在架构中找不到绑定到所访问的已提升属性的属性,则设计器不允许访问它。 另一方面,如果将属性定义为 MessageContextPropertyBase,则消息类型并不重要,并且可以访问该属性。
在自定义管道中,将属性提升或写入上下文的机制非常相似。 若要编写属性,请使用对 IBaseMessageContext Write 方法的调用将值置于上下文中。 对于提升的属性,只需改用 IBaseMessageContext Promote 方法。 其中每个方法都采用属性名称、命名空间和值。 对于已提升的属性,属性的名称和命名空间按照属性架构中的定义,通过引用属性架构程序集,并利用为该属性生成的类中的相应属性,可以最便捷地进行访问。 可分辨字段使用公用命名空间,
http://schemas.microsoft.com/BizTalk/2003/btsDistinguishedFields
用于检索值的 XPath 表达式通常用作名称。下面的代码显示了如何将属性增加和写入上下文的示例。 请注意,在此示例中,正在将一个独特字段写入上下文中。 这仅适用于消息架构标识特定字段的编排,以便编排设计器能够识别该字段。 将属性写入上下文中以供接收或发送端的其他管道组件使用可能很有用。
//create an instance of the property to be promoted
SOAP.MethodName methodName = new SOAP.MethodName();
//call the promote method on the context using the property class for name
//and namespace
pInMsg.Context.Promote(methodName.Name.Name, methodName.Name.Namespace,
"theSOAPMethodName");
//write a distinguished field to the context
pInMsg.Context.Write("theDistinguishedProperty",
"http://schemas.microsoft.com/BizTalk/2003/btsDistinguishedFields",
"theDistinguishedValue");
在将值写入或提升到上下文时,请记住以下事实:
将值写入上下文中,该上下文具有与之前用于提升属性相同的名称和命名空间,这会导致该属性不再被提升。 写入本质上覆盖了促销。
将 null 值写入上下文会删除该值,因为不允许使用 null 值属性。
提升的属性长度限制为 256 个字符,而写入的属性没有长度限制。
推广属性用于消息路由,为了提高比较和存储的效率,其大小受到限制。 虽然写入属性对大小没有硬限制,但在上下文中使用过大的值会对性能产生影响,因为这些值仍必须使用消息进行处理和传递。
当消息准备好从 BizTalk Server 发送时,它会在发送端口中经历补充过程。 在执行发送管道之前,首先将映射应用于消息,使得在通过管道处理并通过适配器发送之前,消息可以被转换为客户或应用程序特定的格式。 在发送管道中,属性从上下文降级到消息中,而不是将属性提升到消息上下文中。