Bilindiği üzere geliştirilen pipelineları orchestrationlar üzerinde çalıştırabiliyoruz ve gelen giden mesajları etkin bir şekilde kullanıyoruz. Fakat bu yazılan pipeline ve componentlerin bir tanesi bu iş için uygun değil. Oda EDIFACT mesajları. Microsoft EDI mesajlarını Pipelinelar üzerinden geçirerek Orchestration içerisinde çalıştırmayı desteklemiyor. (
Eğer EDIFACT mesajlarının geldiği hali koruyarak orchestrationların içerisine almak istiyorsanız Microsoft Pipeline componentleri üzerine pipeline componentler yazarak mesajı ve xml halini elde edebilirsiniz.
Önce bu işi yapacak olacak componenti yazmak gerekiyor. Burada dikkat edilmesi EdiDisassembler i kullanarak kod yazmak.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.BizTalk.Component.Interop;
using System.Runtime.InteropServices;
using Microsoft.BizTalk.Message.Interop;
using System.IO;
using Microsoft.BizTalk.PipelineOM;
using System.Xml;
using Microsoft.BizTalk.Edi.Pipelines;
using Microsoft.BizTalk.Edi.BatchMarker;
using System.Text.RegularExpressions;
using HelperBase.Genel.Executers;
namespace EdiLogDisassembler
{
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
[ComponentCategory("9d0e4100-4cce-4536-83fa-4a5040674ad6"), Guid("4bc3957c-85c1-4c62-a5be-4e4a57b819f7"), ComponentCategory("9d0e4105-4cce-4536-83fa-4a5040674ad6")]
public class LogDisassembler : EdiDisassembler,
IBaseComponent,
IDisassemblerComponent,
IComponentUI,
IPersistPropertyBag
{
Stream strmFile = null ;
public LogDisassembler() { }
# region IBASECOMPONENT
public string Description
{
get
{
return "Edi için Pipeline";
}
}
public string Name
{
get
{
return "LogDisassemblerComponent";
}
}
public string Version
{
get
{
return "1.0.0.0";
}
}
# endregion
# region ICOMPONENTUI
public System.Collections.IEnumerator Validate(object projectSystem)
{
return null;
}
public System.IntPtr Icon
{
get
{
return new System.IntPtr();
}
}
#endregion
#region IPERSISTPROPERTYBAG
public bool Probe(IPipelineContext pContext, IBaseMessage pInMsg)
{
return base.Probe(pContext,pInMsg);
}
public void InitNew()
{
base.InitNew();// TODO: Add LogDisassemblerComponent.InitNew implementation
}
public void Load(IPropertyBag propertyBag, int errorLog)
{
string xmlPropertyBag = "<?xml version=\"1.0\" encoding=\"utf-16\"?><PropertyBag xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"> <Properties> <Property Name=\"XmlSchemaValidation\"> <Value xsi:type=\"xsd:boolean\">false</Value> </Property> <Property Name=\"OverrideFallbackSettings\"> <Value xsi:type=\"xsd:boolean\">true</Value> </Property> <Property Name=\"EdiDataValidation\"> <Value xsi:type=\"xsd:boolean\">true</Value> </Property> <Property Name=\"AllowTrailingDelimiters\"> <Value xsi:type=\"xsd:boolean\">false</Value> </Property> <Property Name=\"UseIsa11AsRepetitionSeparator\"> <Value xsi:type=\"xsd:boolean\">false</Value> </Property> <Property Name=\"PreserveInterchange\"> <Value xsi:type=\"xsd:boolean\">false</Value> </Property> <Property Name=\"EfactDelimiters\"> <Value xsi:type=\"xsd:string\">0x3A, 0x2B, 0x2C, 0x3F, 0x20, 0x27</Value> </Property> <Property Name=\"CreateXmlTagForTrailingSeparators\"> <Value xsi:type=\"xsd:boolean\">false</Value> </Property> <Property Name=\"MaskSecurityInformation\"> <Value xsi:type=\"xsd:boolean\">true</Value> </Property> <Property Name=\"ConvertToImpliedDecimal\"> <Value xsi:type=\"xsd:boolean\">false</Value> </Property> <Property Name=\"RouteAckOn2WayPort\"> <Value xsi:type=\"xsd:boolean\">true</Value> </Property> <Property Name=\"CharacterSet\"> <Value xsi:type=\"xsd:string\">UTF8</Value> </Property> <Property Name=\"DetectMID\"> <Value xsi:type=\"xsd:boolean\">true</Value> </Property> <Property Name=\"UseDotAsDecimalSeparator\"> <Value xsi:type=\"xsd:boolean\">false</Value> </Property> </Properties></PropertyBag>";
PropertyBag propertyBag1 = PropertyBag.DeserializeFromXml(xmlPropertyBag);
base.Load(propertyBag1, 0);
}
public void Save(IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)
{
base.Save(propertyBag, clearDirty, saveAllProperties);
}
public void GetClassID(out Guid classID)
{
classID = new Guid("99534A16-91CF-4186-A7A6-2F5193166299");
}
#endregion
#region IDISASSEMBLERCOMPONENT
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
{
IBaseMessagePart msgPart = pInMsg.BodyPart;
strmFile = msgPart.GetOriginalDataStream();
base.Disassemble(pContext, pInMsg);
}
public IBaseMessage GetNext(IPipelineContext pContext)
{
try
{
IBaseMessage returnIbaseMessage = null;
IBaseMessage iBaseMessage = null;
int bodyPartCount = 0;
while ((iBaseMessage = base.GetNext(pContext)) != null)
{
if (iBaseMessage.GetErrorInfo() != null)
{
IBaseMessage outMsg = pContext.GetMessageFactory().CreateMessage();
outMsg.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true);
outMsg.BodyPart.Data = iBaseMessage.BodyPart.Data;
outMsg.BodyPart.ContentType = iBaseMessage.BodyPart.ContentType;
outMsg.BodyPart.Charset = iBaseMessage.BodyPart.Charset;
outMsg.BodyPart.PartProperties = iBaseMessage.BodyPart.PartProperties;
for (int iProp = 0; iProp < iBaseMessage.Context.CountProperties; iProp++)
{
string strName;
string strNSpace;
object val = iBaseMessage.Context.ReadAt(iProp, out strName, out strNSpace);
if (!strName.ToString().Equals("MessageDestination"))
{
if (iBaseMessage.Context.IsPromoted(strName, strNSpace))
{
if (strName.ToString().Equals("MessageType"))
outMsg.Context.Promote(strName, strNSpace, "Error");
else
outMsg.Context.Promote(strName, strNSpace, val);
}
else
outMsg.Context.Write(strName, strNSpace, val);
}
}
byte[] byteArray = Encoding.ASCII.GetBytes(iBaseMessage.GetErrorInfo().ToString());
MemoryStream stream = new MemoryStream(byteArray);
outMsg.AddPart("Error", pContext.GetMessageFactory().CreateMessagePart(), false);
outMsg.GetPart("Error").Data = stream;
strmFile.Seek(0, SeekOrigin.Begin);
outMsg.AddPart("EdiMessage", pContext.GetMessageFactory().CreateMessagePart(), false);
outMsg.GetPart("EdiMessage").Data = strmFile;
while ((iBaseMessage = base.GetNext(pContext)) != null) ;
return outMsg;
}
if (returnIbaseMessage == null)
{
returnIbaseMessage = iBaseMessage;
}
else
{
returnIbaseMessage.AddPart(iBaseMessage.BodyPartName + bodyPartCount.ToString(), iBaseMessage.BodyPart, false);
returnIbaseMessage.GetPart(iBaseMessage.BodyPartName + bodyPartCount.ToString()).Data = iBaseMessage.BodyPart.Data;
}
bodyPartCount++;
}
if (returnIbaseMessage != null)
{
returnIbaseMessage.AddPart("EdiMessage", pContext.GetMessageFactory().CreateMessagePart(), false);
strmFile.Seek(0, SeekOrigin.Begin);
returnIbaseMessage.GetPart("EdiMessage").Data = strmFile;
}
return returnIbaseMessage;
}
catch
{
throw;
}
}
#endregion
}
}
Bu yazılan component için receive pipeline içeren bir proje hazırlıyoruz ve bu pipeline kullanıyoruz. Böylece mesajın kendisi ve oluşan xml ler orchestration üzerine geliyor. Ayrıca edi dönüşümünde karşılaşacağınız problemleride text halinde orchestration üzerinde görebiliyorsunuz.
Tabi bu oluşan pipeline projesini deploy ediyor ve alacağımız portta receive pipeline olarak seçiyoruz. Orchestration içine mesajı System.Xml.XmlDocument olarak alıyoruz. Ve aşağıdaki kodla mesajı, xml i, varsa hatalarına ulaşabiliyoruz.
Microsoft.XLANGs.BaseTypes.XLANGMessage xLangMessages = MsgIn;
MsgEdi = new System.Xml.XmlDocument();
MsgEdi = xLangMessages[xLangMessages.Count-1];
Microsoft.XLANGs.BaseTypes.XLANGPart xPartError = xLangMessages[xLangMessages.Count-2];
xLangMessages[0]; dönüşüme uğrayan xml edi mesajı.