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