Grabbing the message body with Exchange Transport Agent

Exchange Server 2007 came with a new transport architecture, which you can so joyfully admire on http://technet.microsoft.com/en-us/library/aa996349.aspx.

I had this project where we needed to exchange emails between 2 networks with a different classification, and of course SMTP was one of the protocols that was not allowed to pass the bridge between both networks.

In fact, the only thing that was allowed was xml and this would be enforced with a xml firewall which would validate the xml packets against a set of predefined schema’s.

So, for us to be able to get the message through, we would have to intercept all email traffic, filter them -based on recipients- and serialize the outbound messages to send them through the xml gateway.

A possible solution was writing a Transport Agent that could be plugged into the Exchange Server, and that’s exactly what we did.
Intercepting the messages and route them, based on recipient was easy. There are numerous documents online that show you how to write a Transport Agent that logs all messages, or modifies the recipient list, …

In fact, the hardest part was grabbing the message body, simply because it was always formatted in unicode/utf16, regardless of our efforts to save it in utf8. A lot of older email clients don’t support the display of message bodies in unicode/utf16 and typically you would always see just the first character of the body followed by some weird character.

The solution to this problem lies in the fact that the message body, accessible through the MessageEventArgs e.MailItem.Message..Body.GetContentReadStream() is encoded in unicode/utf16. This should not be a problem if it could be directly streamed to a file with proper encoding defined.

Unfortunately there is no direct way to do this, so we ended up with adding a StreamReader to it, permitting us to read the stream line by line and writing it to a StreamWriter attached to a FileStream.

Even though we specified the StreamWriter to use Encoding.UTF8, somehow the file got always populated with what seemed like Unicode/UTF16. Our mistake was connecting the StreamReader with default arguments to the e.MailItem.Message..Body.GetContentReadStream(). In C#, by default a StreamReader uses utf8 encoding, where our Body was encoded in unicode/utf16. By telling the streamReader tu use Encoding.Unicode (UTF16) we were finally able to properly convert the message body to utf8 and save it to our xml file.

Here’s some code snippet:


StreamReader reader = new StreamReader(e.MailItem.Message.Body.GetContentReadStream(),System .Text.Encoding.Unicode, true);
FileStream fso = new FileStream(workingDir + @"\" + MessageGuid + ".body.processing", FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter writer = new StreamWriter(fso, Encoding.UTF8);
string temp;
while ((temp = reader.ReadLine()) != null)
{
 writer.WriteLine(temp);
}
writer.Flush();
writer.Close();

fso.Close();
reader.Close();

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: