How to: Extract email attachements using a custom pipeline component
To process email attachements through message level, you need to process them using a pipeline. Create a custom receive pipeline with a custom disassemle part.
How to create a custom receive pipeline:
- Create a new solution (templates\ other project types\ visual studio solutions\ blank solution).
- Add new project (Visual C#, class library (is a .dll)).
- Create a new class (visual C# items\ class).
- Add Microsoft.Biztalk.Pipeline.dll (from the install folder).
- Add Microsoft.Biztalk.Pipeline.Components as a reference (from the install folder\ pipeline
components).
- Implement the IBaseComponent, IComponentUI.
- Implement the IDisassembler Component Interface, which is mandatory to implement the getnext and
disassemble methods.
* GetNext: method returns messages resulting from the disassemble method execution.
* Disassemble: used to split or process the incoming message documents.
When we receive an email we receive it as a message associated with multi-parts messages, in the disassemble method we need to loop through each part of the message and create a new message. We will start looping from index 1 because 0 is the body content of the message, which we are not interested in.
At the bottom of this document you will find the full C# code for our custom class.
Build the project and copy the the generated .dll to the BizTalk install folder\ pipeline components.
Create receive Pipeline(or add to existing pipeline)
- Create a new BizTalk project by right clicking the solution and selecting empty BizTalk server project. (Add new project, BizTalk projects, empty BizTalk project).
- Add new item, receive pipeline.
- Right click toolbox window, select choose items, select BizTalk pipeline components and check your
custom component (email attachement extractor).
- Drag and drop the EmailAttachementExtractor to the Disassembler.
- Right click the project, select properties, select sign tab, check sign assembly choose a strong
name key file, select new and rename it.
- Select the deployment tab, set the application name.
- Right click solution and deploy.
Configure Pop3 adapter
- Open the BizTalk Server Administration console.
- Right click Attachement Extractor receive port, select one-way receive port, change the name.
- Select receive location tab, change the name.
- Select the POP3 adapter and configure it (Fill in the correct settings).
- Create a send port, set the name, transport type (FILE), URI (filepath) and send pipeline.
- Select filters tab, set filters to receiveport or POP3.subject == BOUWSHOPONLINE OR
POP3.Subject == SCANORDER.
- Set mapping
- Test the solution.
The full code for our C# class looks like this:
namespace TechNetWiki.AttachmentsExtractor.PipelineComponent
{
using System;
using System.IO;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using System.Runtime.InteropServices;
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
[Guid("01F04E58-7AD8-42EF-A3CB-D939B960E8F9")]
public class AttachmentsExtractor : IBaseComponent, IComponentUI, IDisassemblerComponent
{
#region IBaseComponent Members
/// <summary>
/// Gets Description of the component
/// </summary>
public string Description
{
get
{
return "Email Attachments Extractor";
}
}
/// <summary>
/// Gets Name of the component
/// </summary>
public string Name
{
get
{
return "EmailAttachmentsExtractor";
}
}
/// <summary>
/// Gets Version of the component
/// </summary>
public string Version
{
get
{
return "1.0";
}
}
#endregion
#region IComponentUI members
/// <summary>
/// Component icon to use in BizTalk Editor
/// </summary>
public IntPtr Icon
{
get
{
return System.IntPtr.Zero;
}
}
/// <summary>
/// The Validate method is called by the BizTalk Editor during the build
/// of a BizTalk project.
/// </summary>
/// <param name="obj">An Object containing the configuration properties.</param>
/// <returns>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.</returns>
public System.Collections.IEnumerator Validate(object obj)
{
return null;
}
#endregion
/// <summary>
/// this variable will contain any message generated by the Disassemble method
/// </summary>
private System.Collections.Queue _msgs = new System.Collections.Queue();
#region IDisassemblerComponent members
/// <summary>
/// Returns messages resulting from the disassemble method execution
/// </summary>
/// <param name="pc">the pipeline context</param>
/// <returns></returns>
public IBaseMessage
GetNext(IPipelineContext pc)
{
// get the next message from the Queue and return it
IBaseMessage msg = null;
if ((_msgs.Count > 0))
{
msg = ((IBaseMessage)(_msgs.Dequeue()));
}
return msg;
}
/// <summary>
/// called by the messaging engine when a new message arrives
/// </summary>
/// <param name="pc">the pipeline context</param>
/// <param name="inmsg">the actual message</param>
public void Disassemble(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
var partName = string.Empty;
// we start from index 1 because index zero contains the body of the message
// which we are not interested
for (int i = 1; i < inmsg.PartCount; i++)
{
IBaseMessagePart currentPart = inmsg.GetPartByIndex(i, out partName);
Stream currentPartStream = currentPart.GetOriginalDataStream();
var ms = new MemoryStream();
IBaseMessage outMsg;
outMsg = pc.GetMessageFactory().CreateMessage();
outMsg.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
outMsg.Context = inmsg.Context;
currentPartStream.CopyTo(ms);
string attachmentContent = Encoding.UTF8.GetString(ms.ToArray());
MemoryStream attachmentStream = new System.IO.MemoryStream(
System.Text.Encoding.UTF8.GetBytes(attachmentContent));
outMsg.GetPart("Body").Data = attachmentStream;
outMsg.Context.Write("ReceivedFileName","http://schemas.microsoft.com/BizTalk/2003/file-properties", partName);
_msgs.Enqueue(outMsg);
}
}
#endregion
}
}
Maak jouw eigen website met JouwWeb