Tuesday, February 5, 2008

Sending a mail with an attachment & body text

To send an email-message that has attachment and also has a bodytext you need to work arround a few issues.
Normally you would create a send pipeline with a MIME encoder and set the "send body part as attachment" to True. This however, will cause your email bodytext to state "This message has attachments.", no matter what you've set to be the SMTP.EmailBodyText-value.
To work arround this issue, you have to take the following steps:

  1. Create a custom send pipeline and add a MIME encoder, leave this as is.
  2. In your orchestration view, create a new MultiPartMessageType with 2 Message Parts, a BodyPart and an AttachmentPart. Set the "Message Body Part" property to respectively True and False. Also, set the "Type" property of the BodyPart to the schema of the message you want to add as an attachment.
    The "Type" property of the AttachmentPart should be a .NET Class called "RawString".
    This is a custom class that contains the following code:

using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using Microsoft.XLANGs.BaseTypes;
namespace Microsoft.Samples.BizTalk.XlangCustomFormatters
{
public abstract class BaseFormatter : IFormatter
{
public virtual SerializationBinder Binder
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public virtual StreamingContext Context
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public virtual ISurrogateSelector SurrogateSelector
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public abstract void Serialize(Stream stm, object obj);
public abstract object Deserialize(Stream stm);
}
public class RawStringFormatter : BaseFormatter
{
public override void Serialize(Stream s, object o)
{
RawString rs = (RawString)o;
byte[] ba = rs.ToByteArray();
s.Write(ba, 0, ba.Length);
}
public override object Deserialize(Stream stm)
{
StreamReader sr = new StreamReader(stm, true);
string s = sr.ReadToEnd();
return new RawString(s);
}
}
[CustomFormatter(typeof(RawStringFormatter))]
[Serializable]
public class RawString
{
[XmlIgnore]
string _val;
public RawString(string s)
{
if (null == s)
throw new ArgumentNullException();
_val = s;
}
public RawString()
{
}
public byte[] ToByteArray()
{
return Encoding.UTF8.GetBytes(_val);
}
public override string ToString()
{
return _val;
}
}
}

  1. Then in a message assignement shape, type the following expression:
    (POMessageOut is the outgoing message, POMessageIn is the message you want to attach).

POMessageOut.BodyPart = new Microsoft.Samples.BizTalk.XlangCustomFormatters.RawString("This is the body of the email.");
POMessageOut.AttPart = POMessageIn;

  1. That's pretty much it!

2 comments:

Alexis said...

Today I have opened my MS Outlook Express. I was put out and didn't know what to do next,because of my emails had been corrupted. Luckily I used the Internet and noticed there an interesting software - outlook express e-mail recovery. The program determined my trouble for a minute and completely easy. I am very glad now...

Anonymous said...

Hi Peter
It Works ! Thanks
But unfortunately I have a csv as an attachment and as soon as I add the flatfile assembler it then fails to do so :(
Any clue what could be causing it ?