In BizTalk gibt es einige Alternativen, wie Messages aufgebaut werden können.
Am häufigsten auf Basis XSD-Schema:
https://docs.microsoft.com/en-us/biztalk/core/messages-represented-as-xsd-schemas
Weiterhin in den internen Repräsentationen.
In Orchestrations auf Basis XLANGMessage:
https://docs.microsoft.com/en-us/biztalk/core/messages-represented-as-xlangmessage
In Pipelines auf Basis IBaseMessage:
https://docs.microsoft.com/en-us/biztalk/core/ibasemessage-interface
Es gibt auch die Möglichkeit, Messages auf Basis von .NET Klassen (als .NET Objects) zu erzeugen:
https://docs.microsoft.com/en-us/biztalk/core/messages-represented-as-net-classes.
Wie es mit .NET Klassen geht, soll im Folgenden kurz veranschaulicht werden.
Die Felder FirstName und LastName als String, YearOfBirth als Int.
Als .NET Klasse würde man in der einfachsten Form die Person so formulieren.
[Serializable]
publicclassPersonObj
{
public PersonObj() {}
[DistinguishedField()]
publicString FirstName;
[DistinguishedField()]
publicString LastName;
[DistinguishedField()]
publicInt32 YearOfBirth;
}
Hierbei sind wichtig:
- Das [Serializable] Attribute.
- Der public default Konstruktor public PersonObj() {}.
Falls auf Felder als Distinguished Field zugegriffen werden soll, können sie mit [DistinguishedField()] attributiert werden. Auf Basis dieser Klasse kann nun in einer Orchestration eine Message deklariert werden
Als Beispiel nehmen wir ein simples Person-Modell. Als XSD im BizTalk Schema-Editor so:
Und in einem Assignment Shape wie folgt erstellt und die Felder gesetzt werden:
Mit so erstellten Messages kann sehr bequem in .NET Code gearbeitet werden, direkt mit den Klasseninstanzen, ohne sich mit Xml zu mühen. D.h. wer ohnehin Arbeit in .NET Helpern verrichtet, kann hier bereits einen Vorteil haben. Die so definierte Message wird allerdings von BizTalk, wie auch andere Messages, als Xml serialisiert und sieht “ganz normal“ aus.
<?xmlversion="1.0"?>
<PersonObj
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>Max</FirstName>
<LastName>Mustermann</LastName>
<YearOfBirth>2022</YearOfBirth>
</PersonObj>
Richtig interessant wird es, wenn man für die BizTalk interne Message Serialisierung einen eigenen Formatter implementiert.
[Serializable]
[CustomFormatter(typeof(PersonObjFormatter))]
publicclassPersonObj
{
public PersonObj() {}
[XmlIgnore]
[DistinguishedField()]
publicString FirstName;
[XmlIgnore]
[DistinguishedField()]
publicString LastName;
[XmlIgnore]
[DistinguishedField()]
publicInt32 YearOfBirth;
}
publicclassPersonObjFormatter : IFormatter
{
publicSerializationBinder Binder
{
get { thrownewNotSupportedException(); }
set { thrownewNotSupportedException(); }
}
publicStreamingContext Context
{
get { thrownewNotSupportedException(); }
set { thrownewNotSupportedException(); }
}
publicISurrogateSelector SurrogateSelector
{
get { thrownewNotSupportedException(); }
set { thrownewNotSupportedException(); }
}
publicobject Deserialize(Stream serializationStream)
{
PersonObj personObj = newPersonObj();
BinaryReader r = newBinaryReader(serializationStream);
personObj.FirstName = r.ReadString();
personObj.LastName = r.ReadString();
personObj.YearOfBirth = r.ReadInt32();
return personObj;
}
publicvoid Serialize(Stream serializationStream, object graph)
{
PersonObj personObj = (PersonObj)graph;
BinaryWriter w = newBinaryWriter(serializationStream);
w.Write(personObj.FirstName);
w.Write(personObj.LastName);
w.Write(personObj.YearOfBirth);
}
}
Hierbei sind wichtig:
- Der custom Formatter PersonObjFormatter, der das IFormatter Interface implementiert.
- Die entsprechende Attributierung [CustomFormatter(typeof(PersonObjFormatter))] der PersonObj Klasse.
- Mit dem [XmlIgnore] Attribut wird das Felder-Handling durch den Xml Serializer verhindert.
- Die Deserialize und die Serialize Methoden des Formatters implementieren das Handling der binär serialisierten Nachricht.
Eine so definierte Person-Message wird nun von BizTalk binär serialisiert und sieht so aus (als Hex):
Die serialisierte Nachricht ist jetzt nur 19 Byte gross, im Vergleich dazu die Grösse der gleichen Nachricht als Xml = 173 Byte! Das kann auch sehr schön in der BizTalkMsgBoxDb geprüft werden.
Zum Abschluss ein paar mögliche Vorteile auf .NET Klassen basierender Nachrichten:
- Vereinfachte Arbeit mit den Messages in .NET Helpern (in komplexen Szenarien).
- Höhere Performance (besonders bei großen Messages) da schnellere Serialisierung/Deserialisierung im Vergleich zu XML, sowie geringerer Datentransfer.
- Deutlich geringere Speichergröße (je größer die Messages, desto klarer der Vorteil).
- Der Serialisierungs-Mechanismus erlaubt es auf einfache Art, beliebigen Message-Output zu erzeugen und beliebigen Message-Input zu konsumieren. z.B. Plain Text, spezifische Dateiformate, binäre Streams.
Viel Freude beim Programmieren mit BizTalk Object Messages!
Plamen Petrow
QUIBIQ Schweiz