I started with this excellent working unzip pipeline component here (by Rui Machado).
I made the following changes to that code:
1) Put it in MyCompany.Common.etc… namespace and project (not shown here)
2) Added a Property Bag Item called FileMask (and a one for future use called “ParmReserved1” (this is standard coding, so I didn’t include here).
3) Added the FitsMask function from StackOverflow
4) Added the functionality to set the %SourceFileName% (aka ReceivedFileName, based on the files inside the zip instead of the zip file dropped).
public void Disassemble(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
IBaseMessage Temp = inmsg;
// uses Ionic.Zip
using (ZipFile zip = ZipFile.Read(inmsg.BodyPart.GetOriginalDataStream()))
{
foreach (ZipEntry e in zip)
{
string strCheckFileName = System.IO.Path.GetFileName(e.FileName);
if (FitsMask(strCheckFileName, FileMask))
{
var ms = new MemoryStream();
IBaseMessage outMsg;
outMsg = pc.GetMessageFactory().CreateMessage();
outMsg.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
outMsg.Context = inmsg.Context;
// Neal Walters - 05/08/2017 - added promoted field with the filename -
// This allows us to use the %sourcefilenam% macro in the SendPort to name the file.
outMsg.Context.Write("ReceivedFileName",
"http://schemas.microsoft.com/BizTalk/2003/file-properties",
strCheckFileName);
e.Extract(ms);
string XMLMessage = Encoding.UTF8.GetString(ms.ToArray());
MemoryStream mstemp = new System.IO.MemoryStream(
System.Text.Encoding.UTF8.GetBytes(XMLMessage));
outMsg.GetPart("Body").Data = mstemp;
_msgs.Enqueue(outMsg);
}
}
}
}
private static bool FitsMask(string fileName, string fileMask)
{
string pattern =
'^' +
Regex.Escape(fileMask.Replace(".", "__DOT__")
.Replace("*", "__STAR__")
.Replace("?", "__QM__"))
.Replace("__DOT__", "[.]")
.Replace("__STAR__", ".*")
.Replace("__QM__", ".")
+ '$';
return new Regex(pattern, RegexOptions.IgnoreCase).IsMatch(fileName);
}
The screen shot below show how the FileMask can be specified in the RecieveLocation (via use of the standard Property Bag interface):
(Sorry, don't have SnagIt yet at this client, so have to use the poor man's Snipping Tool).