我尝试创建一个自定义BizTalk 2013 R2(接收或发送)管道,该管道可以将包含一些txt文件的xxx.GZ文件解压缩到发送端口。
这是我到现在为止所尝试的:
PS。我使用.Net的IO GZip类。
创建了一个BTS应用程序,配置了接收位置和发送端口。
接收位置使用我创建的自定义管道,这是我尝试的自定义管道的代码:
public void Disassemble(IPipelineContext pc, IBaseMessage inmsg)
{
IBaseMessagePart bodyPart = inmsg.BodyPart;
if (bodyPart != null)
{
Stream originalStream = bodyPart.GetOriginalDataStream();
if (originalStream != null)
{
using (GZipStream gZipInputStream = new GZipStream(new MemoryStream(originalStream.ReadByte()), CompressionMode.Decompress))
{
MemoryStream memStream = new MemoryStream();
byte[] buffer = new Byte[1024];
int bytesRead = 1024;
while (bytesRead != 0)
{
bytesRead = gZipInputStream.Read(buffer, 0, buffer.Length);
gZipInputStream.CopyTo(buffer, 0);
memStream.Write(buffer, 0, bytesRead);
}
IBaseMessage outMessage;
outMessage = pc.GetMessageFactory().CreateMessage();
outMessage.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
memStream.Position = 0;
outMessage.BodyPart.Data = memStream;
outMessage.Context = PipelineUtil.CloneMessageContext(inmsg.Context);
_msgs.Enqueue(outMessage);
}
}
}
}
此代码似乎无法正常工作。只需发送GZ文件而不将其解压缩到发送端口。我在接收位置端口使用已实现的管道。以下是它的工作原理:当BizTalk在其接收位置接收GZ打包文件时,它只将文件发送到订阅此接收位置的发送端口。似乎管道对GZ流没有做任何事情。它应该做的是解压缩GZ文件并将所有解压缩的文件发送到发送端口,这指向需要放置解压缩文件的文件夹。
我试图谷歌没有运气,存在的样本似乎不适合我。
所以任何人都可以帮助我或告诉我在我的代码中做错了什么。我只是想实现一个C#自定义BizTalk 2013 R2(接收或发送)管道,可以将收到的GZ文件解压缩到发送端口(指向文件夹),该文件包含一些txt文件?
更新
由于Dissambler版本没有用,我创建了一个解码版本。
以下是管道中的解码代码:
#region IComponent members
/// <summary>
/// Implements IComponent.Execute method.
/// </summary>
/// <param name="pc">Pipeline context</param>
/// <param name="inmsg">Input message</param>
/// <returns>Original input message</returns>
/// <remarks>
/// IComponent.Execute method is used to initiate
/// the processing of the message in this pipeline component.
/// </remarks>
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
if (null == pc) throw new ArgumentNullException("pContext", "Pipeline context can not be null");
if (null == inmsg) throw new ArgumentNullException("pInMsg", "Input message can not be null");
IBaseMessagePart bodyPart = inmsg.BodyPart;
if (bodyPart != null)
{
GZipStream strm = new GZipStream(bodyPart.GetOriginalDataStream(), CompressionMode.Decompress);
bodyPart.Data = strm;
pc.ResourceTracker.AddResource(strm);
}
return inmsg;
}
#endregion
如何在GZip文件中获取每个文件的正确文件名?因此,当消息发送到发送端口时,它应该使用正确的文件名写入文件。
答案 0 :(得分:1)
看起来您将自定义管道组件实现为Disassemble阶段,由于以下两个原因,它实际上应该是Decode阶段管道组件。
请参阅MSDN Receive Pipelines
解码阶段
- 此阶段用于解码或解密消息的组件。
- 如果需要将传入的消息从一种格式解码到另一种格式,则应将MIME / SMIME解码器管道组件或自定义解码组件置于此阶段。
- 此阶段收到一条消息并生成一条消息。
- 此阶段可包含0到255个组件。
- 此阶段中的所有组件都已运行。
反汇编阶段
此阶段用于解析或反汇编邮件的组件。
- 此阶段中的组件会探测消息,以查看是否识别了消息的格式。基于对格式的识别,其中一个组件反汇编了消息。
- 如果此阶段包含多个组件,则仅运行识别邮件格式的第一个组件。如果阶段中没有任何组件识别出消息格式,则消息处理将失败。
- 此阶段应包括任何实现特殊行为以反汇编邮件内容的自定义组件。
- 此阶段可包含0到255个组件。如果阶段中没有组件,则会传递消息。
更新:随着您的更新问题,它变得有点棘手。如果必须将消息拆分为多个消息,则可以执行此操作的唯一阶段是“反汇编”阶段。所以你必须回到那个版本并进行调试,找出它为什么不执行解压缩。
Zip Disassembler UnzipDisassembler - A custom pipeline component for BizTalk Server 2004有一个旧代码示例,用于Zip文件而不是Gzip。但它遵循相同的模式。您还需要一种类似于GetNextEntry的方法来发布消息,然后解析下一个文件。在outmsg创建阶段,您可以设置文件名等上下文属性。