Gokul's Blog


Leave a comment

POP3 and BizTalk

(original Publish date: April 16, 2008)
Abstract : Receive an email from an POP3 server and write the attachments in to a folder.

Solution 1: Use the BizTalk 2006 R2 POP3 adapter and an orchestration to achieve it.

The receive location has to be configured as follows.

[Image] of POP3 receive location

I was able to get the filename by getting the message partname while I was using Gmail POP3 as my POP3 server, when we switched to Windows POP3 server I was unable to get the Filename. The algorithm used by BizTalk POP3 adapter to get the filename is as follows

1. Take it from the Content-Description header.
2. If not found, then the part name is based on the Content-ID header.
3. If still not found, then generate a GUID for the part name.

Receive the email as a Multipart message and then loop through the parts. While looping through check whether the MIME.FileName property exists if not then its the body part :).

Please find the attached zip file containing the orchestration code. This orchestration sample will read an email and write the attachments one by one to a folder.

Solution 2: While I was exploring through various options to overcome the issue. I came across an interesting scenario. If you just need a file which contain the email with all the contents in a folder. .eml comes to the rescue. Read the email using a receive port and write the message using a send port with an  .eml extension. When a user double-click on this file it opens in outlook express and its very simple solution(15 minutes we can achieve this). This solution suits for environments where outlook express is allowed.

Solution 3: Use the Raw Message send it to a helper method there are a lot of third party .Net based MIME encoding tools. Manipulate the message as needed. A google search on .Net mime encoding returns a lot of tools. An excellent article from Roy Ashbrook explains how to use Regex to parse .eml files.

Here is the code for reference taken from the above blog.

using System;
using System.IO;
using System.Text.RegularExpressions;
 
namespace parse.eml
{
    class Email
    {
        string _path,_to,_from,_subject,_urls;
 
        public Email(string path)
            {
                _path = path;
                string fc = new StreamReader(path).ReadToEnd();
                _from = Regex.Matches(fc, "From: (.+)")[0].ToString();
                _to = Regex.Matches(fc, "To: (.+)")[0].ToString();
                _subject = Regex.Matches(fc, "Subject: (.+)")[0].ToString();
                _urls = string.Empty;
                foreach (Match m in Regex.Matches(fc,@"https?://([a-zA-Z\.]+)/"))
                {
                _urls += m.ToString() + ' ';
                }
            }
            
            public void show()
            {
                Console.WriteLine("{0}\n\t{1}\n\t{2}\n\t{3}\n\t{4}",_path, _to, _from, _subject, _urls);
            }
     }
        
    class Program
    {
        static void Main(string[] args)
        {
            foreach (string f in Directory.GetFiles(".", "*.eml"))
            {
            Email e = new Email(f);
            e.show();
            }
        }
    }
} //namespace
      
 
Reference articles:

http://www.biztalkgurus.com/forums/p/2217/4455.aspx#4455

http://www.biztalkgurus.com/files/folders/biztalk_2006_samples/entry15562.aspx

And also I would like to thank my friends/ Mandi(MS-support) for their guidance, in getting "solution 1" possible.

Solution 2 coming soon!

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }


Leave a comment

Sending multiple attachments with SMTP Adapter

I’ve received a number of questions regarding a sample I posted a while ago: Arbitrary Binary Attachments to Multi-Part Messages; mostly related to issues when sending the resulting messages through the SMTP adapter and not all attachments (or no attachments at all) getting to the destination account.

I’ve found that usually, this is the result of setting the SMTP.MessagePartsAttachments property to the wrong value. In the sample I posted alongside the article, I was setting the property to 2. I didn’t give any explanation about it at the time, but contrary to what it may intuitively appear, you don’t set this property to the number of attachments (parts) you want to send alongside the message.If you attach 4 different parts to the message, you don’t set the property to the value 4.

Instead, the value 2 means "Send all parts as attachments", which is exactly the behavior you want. For completeness sake, here’s what each possible value for this property means (taken from the BizTalk documentation):

  • 0 – No BizTalk message parts will be used as attachments.
  • 1- The BizTalk message body part is sent as an e-mail attachment. In this case, the EmailBodyFile or EmailBodyText properties should be specified. If neither of these properties are specified, the BizTalk message body part is sent as the e-mail body instead of as an attachment.
  • 2 – All parts are sent as attachments. However, if EmailBodyText or EmailBodyFile are not specified, then the BizTalk message body part is sent as the e-mail body and other parts are sent as attachments.
  • The above article is taken from Tomas Restrepo’s blog. Link to Original Article

    Configuring Dynamic Send Port

    This has to be set in the MessageAssignment shape of myMsg:
    myMsg(SMTP.SMTPHost) = "localhost";
    myMsg(SMTP.From) = "sendmail@testingtvgingestmail.com";
    myMsg(SMTP.Subject) = "From Binary Attachments";
    myMsg(SMTP.MessagePartsAttachments) = 2;

    In a Expression shape, set this value for the Dynamic Send Port:
    MyDynamicSendPort(Microsoft.XLANGs.BaseTypes.Address) = System.Configuration.ConfigurationManager.AppSettings["FileorSMTPEmail"];
    The above value is taken from the configuration file. I have done this way so that we can write  to File System or send to email.
    Example:
    1. <!–<add key="FileorSMTPEmail" value="file://E:\testFileLocation\BinaryAttachments\test.xml"/>–> 
    2 .<add key="FileorSMTPEmail" value="mailto:sendmail@testmailsource.com"/>

    Technorati Tags: ,


    Leave a comment

    Programmatically create an XML document from BizTalk Schema

    programmatically create an XML document based on your XML schema? Or even better, what if you can use the schema that is validated and compiled by BizTalk and stored in the BizTalk management database?
    This way you don’t have to worry about manually keeping the schema and the external XML file in synch since there is no external XML file any more. Any change you make in the schema is directly reflected in the Pipeline component when you build your new message. Well, it turns out that there is an undocumented API called “CreateXmlInstance” just for that. Here is the code snippet that does this.

    using Microsoft.BizTalk.ExplorerOM;
    using Microsoft.BizTalk.Component.Interop;
    Add reference to the assemblies :
    Microsoft.BizTalk.ExplorerOM ==> C:\Program Files\Microsoft BizTalk Server 2006\Developer Tools\Microsoft.BizTalk.ExplorerOM.dll,
    Microsoft.BizTalk.Pipeline ==> C:\Program Files\Microsoft BizTalk Server 2006\Microsoft.BizTalk.Pipeline.dll

    public XmlDocument CreateXmlDoc(string sSchemaName)
            {
                XmlDocument doc = new XmlDocument();
                BtsCatalogExplorer explorer = new BtsCatalogExplorer();
    
                explorer.ConnectionString = @"Integrated Security=SSPI; Server=localhost\SQL2005; Database=BizTalkMgmtDb;";
                Schema mySchema = explorer.Schemas[sSchemaName];
    
                if (mySchema != null)
                {
                    DocumentSpec spec = new DocumentSpec(sSchemaName, mySchema.BtsAssembly.DisplayName);
                    StringWriter sw = new StringWriter(new StringBuilder());
                    doc.Load(spec.CreateXmlInstance(sw));
                    sw.Dispose();
                }
                return doc;
            } 

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }



    This code goes directly to the BizTalk management database, gets the specified schema, and then create an empty XML document based on the schema.

    From here on, you can programmatically populate/manipulate the XML element/attribute values as needed. One thing to note is that this code is not entirely immune to changes either. If you add new elements/attributes to your schema (which is the case for most situations), the code will be fine since it simply creates blank values for the new fields. However, if you remove some elements/attributes, or make changes to existing elements/attributes, and if your subsequent processing code access them, you will have to modify the code to accommodate the changes.


    Leave a comment

    Pipeline Testing – BizTalk

    A good pipeline testing library has been published by Tomas Restrepo, which makes pipeline testing easier than using MS – PIPELINE.exe tool. Check this page/ tool for more information.

    http://www.winterdom.com/weblog/2007/08/09/PipelineTesting11Released.aspx

    Tool : Pipeline Testing Library

    Refer to this article from Michael Stephenson which gives a detailed explanation on using this library for pipeline testing.

    http://geekswithblogs.net/michaelstephenson/archive/2008/03/30/120852.aspx