// CHANGE: Voeg aan het project een referentie toe naar Microsoft.BizTalk.Messaging.dll (in BizTalk installatie folder onder program files). // CHANGE: Voeg aan het project een referentie toe naar Microsoft.BizTalk.Pipeline.dll (in BizTalk installatie folder onder program files). // CHANGE: Voeg aan het project een referentie toe naar System.Drawing (alleen als we een icoontje willen meegeven in de taakbalk). // CHANGE: Wijzig hier de namespace namespace NameSpaceNaam { using System; using System.IO; using System.Text; using System.Drawing; using System.Resources; using System.Reflection; using System.Diagnostics; using System.Collections; using System.ComponentModel; using Microsoft.BizTalk.Message.Interop; using Microsoft.BizTalk.Component.Interop; using Microsoft.BizTalk.Component; using Microsoft.BizTalk.Messaging; [ComponentCategory(CategoryTypes.CATID_PipelineComponent)] // CHANGE: Geef hier een unieke GUID. Gebruik dezelfde GUID in GetClassID. [System.Runtime.InteropServices.Guid("12345678-1234-abcd-abcd-12344321abcd")] // CHANGE: Hier kan je de plaats beperken waar het pipelinecomponent toegevoegd kan worden. // Door dit op CATID_Any te laten staan kan het op elk stadium in een pipeline control. [ComponentCategory(CategoryTypes.CATID_Any)] // CHANGE: Pas hier de classe naam van de pipeline component aan. public class PipelineNaam : Microsoft.BizTalk.Component.Interop.IComponent, IBaseComponent, IPersistPropertyBag, IComponentUI { #region IBaseComponent members /// /// Naam van het pipeline component /// [Browsable(false)] public string Name { get { // CHANGE: Geef hier de naam retour die het component krijgt in de toolbox. return "Pipeline naam"; } } /// /// Versie van het pipeline component /// [Browsable(false)] public string Version { get { // CHANGE: Geef hier de major.minor versie aan van het component. return "1.0"; } } /// /// Korte omschrijving van het component /// [Browsable(false)] public string Description { get { // CHANGE: Geef hier een korte omschrijving van het component. return "Omschrijving van het component."; } } #endregion #region Pipeline properties // CHANGE: Voeg hier alle properties toe die je beschikbaar wil stellen aan // het pipeline component. LET OP: Denk hier goed over na. Het is heel irritant om // later nog weer properties toe te voegen, te verwijderen of namen / types te // veranderen. private string _VoorbeeldProperty = string.Empty; public string VoorbeeldProperty { get { return _VoorbeeldProperty; } set { _VoorbeeldProperty = value; } } #endregion #region IPersistPropertyBag members /// /// Gets class ID of component for usage from unmanaged code. /// /// /// Class ID of the component /// public void GetClassID(out System.Guid classid) { // CHANGE: Geef hier dezelfde GUID retour die boven de class declaratie is gebruikt. classid = new System.Guid("12345678-1234-abcd-abcd-12344321abcd"); } /// /// not implemented /// public void InitNew() { } /// /// Loads configuration properties for the component /// /// Configuration property bag /// Error status public virtual void Load(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, int errlog) { object val = null; // CHANGE: Herhaal dit voor alle properties die je hebt toegevoegd. // Uit de propertybag zet / schrijf je altijd objects. Cast die objects // dus naar het juiste type. val = this.ReadPropertyBag(pb, "VoorbeeldProperty"); if ((val != null)) { this._VoorbeeldProperty = ((string)(val)); } } /// /// Saves the current component configuration into the property bag /// /// Configuration property bag /// not used /// not used public virtual void Save(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, bool fClearDirty, bool fSaveAllProperties) { // CHANGE: Herhaal dit voor alle properties die je hebt toegevoegd. this.WritePropertyBag(pb, "VoorbeeldProperty", this.VoorbeeldProperty); } #region utility functionality /// /// Reads property value from property bag /// /// Property bag /// Name of property /// Value of the property private object ReadPropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName) { object val = null; try { pb.Read(propName, out val, 0); } catch (System.ArgumentException) { return val; } catch (System.Exception e) { throw new System.ApplicationException(e.Message); } return val; } /// /// Writes property values into a property bag. /// /// Property bag. /// Name of property. /// Value of property. private void WritePropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName, object val) { try { pb.Write(propName, ref val); } catch (System.Exception e) { throw new System.ApplicationException(e.Message); } } #endregion #endregion #region IComponentUI members /// /// Component icon to use in BizTalk Editor /// [Browsable(false)] public IntPtr Icon { get { // CHANGE: Dit is het icoontje in de toolbar. Het moet een 32x32 bitmap // zijn. Momenteel maken we een afbeelding met in rood de tekst PC. // Pas dat aan naar een andere toolbar icon indien gewenst. Bitmap b = new Bitmap(32, 32); Graphics g = Graphics.FromImage(b); g.DrawString("PC", new Font("Verdana", 8, FontStyle.Bold), Brushes.Red, 0, 0); g.Save(); return b.GetHicon(); } } /// /// The Validate method is called by the BizTalk Editor during the build /// of a BizTalk project. /// /// An Object containing the configuration properties. /// The IEnumerator enables the caller to enumerate through a collection of strings containing error messages. These error messages appear as compiler error messages. To report successful property validation, the method should return an empty enumerator. public System.Collections.IEnumerator Validate(object obj) { // example implementation: // ArrayList errorList = new ArrayList(); // errorList.Add("This is a compiler error"); // return errorList.GetEnumerator(); return null; } #endregion #region IComponent members /// /// Implements IComponent.Execute method. /// /// Pipeline context /// Input message /// Original input message /// /// IComponent.Execute method is used to initiate /// the processing of the message in this pipeline component. /// public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg) { // CHANGE: Hier gebeurd het echte werk. De execute methode krijgt het bericht door. // Je kan er mee doen wat je wil. // Voorbeeld: Dit vraagt de bestandsnaam op: string received = inmsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties").ToString(); // Zie hier https://blogs.msdn.microsoft.com/mattlind/2006/08/10/accessing-and-listing-message-context-properties-in-pipeline-components/ // voor alle andere bericht eigenschappen die je uit kan vragen / in kan stellen. // Voorbeeld: Hiermee pas je de ReceivedFileName aan. Als een verder poort het bestand // wegschrijft met %SourceFileName% dan zal die vanaf dat moment de aangepaste naam hanteren. inmsg.Context.Write("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", "AangepasteNaam.txt"); // Voorbeeld: inmsg.BodyPart.Data is de daadwerkelijke inhoud van het bestand. // Hier lezen we de hele data uit naar een string (fulldata). string fullData = string.Empty; if (inmsg.BodyPart != null) { using (StreamReader sr = new StreamReader(inmsg.BodyPart.Data)) { fullData = sr.ReadToEnd(); } } // Voorbeeld: Hier passen we de berichtinhoud aan naar iets anders. // We schrijven de aanpassingen via een streamwriter naar een memorystream. // Spoelen die terug en zetten de bericht data op die memorystream. // De memorystream voegen we toe aan de resourcetracker zodat die ook netjes // opgeschoond raakt op het moment dat dit niet meer nodig is. fullData = "Nieuwe of aangepaste bericht inhoud"; MemoryStream ms = new MemoryStream(); // Let op, zet deze niet in een using, dan is het straks een closed stream. StreamWriter sw = new StreamWriter(ms); sw.Write(fullData); sw.Flush(); ms.Position = 0; inmsg.BodyPart.Data = ms; pc.ResourceTracker.AddResource(ms); // Voorbeeld: aan het einde geef je dus weer de inmsg terug. Retourneer je // NULL dan is dat net alsof dat er nooit een bericht is doorgekomen. Er // wordt dan dus ook geen bericht naar de messagebox gezet en zal ook geen // "no subscribers" bericht volgen. Als je alles wat er moet gebeuren in deze // pipeline afwerkt is het aan te raden een property op te nemen "ReturnMessage" // die bij false NULL terug geeft (zo kan men het altijd true zetten als ze // via een send poort een backup willen maken etc). // Installatie: // Een custom pipeline component build je, dan voeg je hem toe aan de // Pipeline Components folder onder de BizTalk applicatie folder. // Sluit visual studio en start hem opnieuw. Op dat moment kan je // in een BizTalk project een pipeline toevoegen en dit component vanuit // de toolbar toevoegen en slepen naar de pipeline. Die pipeline build je // ook, die voeg je in BizTalk toe als resource en dan moet het werken. // Een custom pipeline zoals dit is dus nog niks, het moet altijd in een // pipeline component van een BizTAlk project worden gezet. return inmsg; } #endregion } }