心无旁骛,专注于biztalk......
一. 概述... 1
二. 消息的结构... 1
三. 消息的类型... 2
1. 平面文件... 2
2. Xml文档... 2
3. .net class. 2
4. 二进制数据... 2
四. .net class类型的序列化... 2
五. .net class类型的消息... 3
1. 类要设置为可序列化... 3
2. 类中只包含公共属性和字段... 3
3. 设置名称空间... 3
4. 设置可分辨字段和升级属性... 3
4.1. 设置可分辨字段... 3
4.2. 设置升级属性... 3
5. 一个.net class消息类型的完整代码... 4
六. Biztalk如何处理.net class类型的消息... 5
七. Orchestration中从零开始新建一个xml类型的消息... 5
1. 在消息构造形状中构造新xml消息... 5
2. 在消息构造形状中构造新.net class类型消息... 5
3. 从零开始构造新xml类型消息... 6
3.1. 设置xml文件属性... 6
3.2. 写一个从嵌入资源中读取xml文件内容的方法... 6
3.3. 在消息赋值形状中调用读取xml文件的方法... 7
一. 概述
一般来讲,在biztalk项目中使用的消息都是基于xsd的xml消息,因为这是biztalk最擅长处理的消息。Biztalk整个体系架构都是建构在xml基础之上,在biztalk内部用xml来处理消息,在message box的存储形式也是xml。
但是这并不表示biztalk只能处理xml消息,事实上,biztalk可以处理消息类型可以是平面文件、xml类型、可序列化的.net class或者其他任意的二进制数据流。
这里要讨论的是在biztalk中,尤其是在orchestration中如何使用.net class类型消息。
BizTalk中每条消息都可视为多部分消息,此消息可以由零个或多个部分组成。具有一个或多个部分的消息都具有一个标识为正文部分的部分(但是只能有个一部分标识为正文)。每个部分均由可表示 XML 文档、平面文件、序列化的 .NET 类或其他二进制数据流的二进制数据块组成。
一般的开发biztalk项目体验中,大多是新建一个消息,然后给这个消息指定一个xsd作为这个消息的类型。感觉上一个消息就只能指定一个xsd类型(也可以指定为一个序列化的.net class类型),跟一个xsd相关。其实这样通过这样方式建立的消息也是多部分消息,只是这个消息只有一个正文部分而已。
如果要建立真正有多个部分的消息类型,可以在orchestration view面板中的Types窗格中,展开Types,在Multi-part Message Types下新建一个多部分消息类型,在新建的多部分消息类型中可以建立多个部分,每个部分分别指定类型,还要指定其中的一个部分为正文部分。以后新建消息把消息类型指定为这个多部分消息类型,这个新建消息就是一个具有多个部分的消息了。
注意
任何消息在biztalk的表现都是一个多部分的消息,不过一般的消息只有一个正文部分。
从上面的叙述可以得知,每个消息其实都是多部分消息,一般来讲每个消息至少有一个部分,也可能有多个部分,不管是只有一个部分还是有多个部分,其中必须有一个部分被指定为正文部分,整个消息的类型就由正文部分的消息类型决定。如果正文部分分别为以下情况时,如何确定消息的类型:
平面文件进入到biztalk都会在接收管道中都会被平面文件拆装器拆解为xml的格式,有一个经过平面文件扩展后的xsd架构跟其对应,所以平面文件可以被认为也是xml的消息类型。参看下面的xml文档部分。
Xml消息的消息类型由xml消息的命名空间(后接 # 符号)和xml消息根节点的名称组成。比如,一个xml消息的根结点的名称空间是“http://tempuri.org/samples/MessageType”,xml消息的根结点的名称是Message,那么这个消息的类型就是:http://tempuri.org/samples/MessageType#Message
.net class类型的消息同样是由名称空间加上根元素名称组成。
.net class类型的消息的名称空间由class类的System.Xml.Serialization.XmlRootAttribute属性指定,在定义.net class类时可以在类名前加上相关attribute来指定这个类的一些类级别的attribute(请参考第五部分“.net class类型消息”中的详细定义一个.net class的完整代码),System.Xml.Serialization.XmlRootAttribute中用Namespace参数指定此类的名称空间。
定义.net class的类名就相当于xml类型的根元素。
“名称空间#类名”就是.net class消息的消息类型,跟一般xml消息一样,.net class消息类型也可以作为订阅消息的条件。
二进制数据流的消息类型需要由定制的接收管道把消息类型升级到消息的上下文,一般的二进制数据流的消息类型使用全限定的类型名。
这种情况这里不加讨论,如有必要,以后用专文来探讨二进制数据流消息的情况。
Biztalk中的消息必须是可以序列化的,原因很简单,biztalk中消息不管是从外部进来,还是由orchestration产生的消息,统统都要被保存在Message Box数据库中,要能被保存在数据库中持久保存,消息就必须能被序列化。
还有一点,在长时间运行的orchestration中,运行的周期可能是一天、几天、十几天,甚至可能几个月。在这么长的时间中,一个orchestration实例由始至终都运行在内存中是及其不明智的做法,将耗费大量的资源。所以biztalk设计了一个dehydrat(分解)和rehydrat(重组)的机制,在orchestration实例空闲的时候,把orchestration实例和相关的状态和消息序列化保存到数据库,一旦有消息激活这个orchestration实例时,再把这个orchestration实例和相关状态消息反序列化到内存继续运行。
对.net class序列化Dotnet框架支持两种序列化方式,可以把类序列化为xml格式,也可以把类序列化为二进制格式。
二进制序列化是把对象转换成一串二进制的数据流,二进制序列化保持类型保真度,可以最真实的保存一个对象的全部状态。
Xml序列化是把对象转换成一个xml文档,XML 序列化仅序列化公共属性和字段,且不保持类型保真度。但对于biztalk应用中使用的.net class一般就是使用了类的公共属性和字段。
Biztalk内建直接支持.net class序列化,就是说在biztalk中使用.net class的消息不用开发者自己考虑.net class消息如何如何序列化和反序列化。Biztalk内建.net class消息序列化使用的是xml序列化方式。
二进制序列化方式不是biztalk内建支持的序列化方式,可以选择对.net class消息进行二进制的序列化,但是这需要开发者做更多的工作,需要写代码对消息进行二进制的序列化和反序列化,并定制自己的拆装器和组装器对消息进行序列化和反序列化的工作。
本文只讨论xml序列化的方式,对于二进制序列化的方式,如有必要以后再用专文讨论。
Biztalk中使用.net class需要考虑作为消息的特点,跟一般的类有些不同,一般要注意以下几点:
在定义类前加上表示可以序列化的attribute:[Serializable()]
一般类中的公共属性和字段会被转换为xml文档中的元素,私有属性没什么意义,方法对转成xml也没什么意义。
名称空间是构成消息类型的一部分,.net class转成xml也可以带有名称空间,看下面的代码,名称空间由定义类前的“[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://myURL")]”设置,表示这个类转成xml的Target Namespace是"http://myURL"。
另外类的名称就相当于xml的根元素名称,跟上面的名称空间一起组合成消息的类型。
如果没有设置名称空间,则此.net class消息的类型就是类名称。
在.net class类型中同样可以设置可分辨字段和升级字段。
设置可分辨字段很简单,在需要设置的公共属性或字段前加上“[DistinguishedField]” attribute即可,表示这个公共属性或字段已被设置为可分辨字段。
设置升级属性同xsd中设置升级属性类似,首先也先有一个属性架构,然后在需要升级为属性的公共属性或字段前用“Property”attribute指定关联到哪个属性。如下面的代码中的:
[Property(typeof(netClassMessage_PromoteXSD.PropertyName))]
public string PropertyName
这表示要把公共属性PropertyName升级,并关联到属性架构netClassMessage_PromoteXSD中的PropertyName属性。
.net class类型的消息从外部进入biztalk,.net class类型消息在进入到biztalk时的存在形式必定是被序列化后的xml形式(这里只讨论xml序列化的情况)。
所以,对入站的.net class类型消息需要使用xml拆装器,.net class类型消息序列化后同样有名称空间和根元素,并且也跟一般的xml消息类型一样,名称空间和根元素也决定了这个.net class消息的消息类型。
同样,.net class消息根一般xml消息一样根据消息类型被路由到订阅此消息的orchestration。
.net class消息在orchestration中的存在形式还是xml形式,只有在消息构造形状中对.net class