Jeff's Blog

MS Exchange 2007 Transport Agents

I haven't blogged in a while because I have been buried in work writing a new ticketing system based on Exchange 2007 and Outlook 2007. Most of what we're doing is fairly unexplored (or at least undocumented) territory. For those who have used Event Sinks in previous versions of Exchange, you maybe be happy (or disappointed depending upon your point of view) to find out that Microsoft is deprecating Event Sinks and replacing them with Transport Agents. In my numerous hours scouring the Internet looking for information on how these are implemented, I found just two worthwhile resources:

Transport Agent Tutorial
http://msexchangeteam.com/archive/2006/12/04/431755.aspx

Transport Agent Sample
http://msdn2.microsoft.com/en-us/library/aa579185.aspx

The first is a blog post from a member of the MS Exchange team, on the other is a sample listed in Technet. Furthermore, nearly all code you'll find regarding Transport Agents in written in C#. While I have nothing against C# and actually come from a Java background, more of our team is familiar with VB.NET and I feel it's more human readable. According to Microsoft and the Exchange team, "Agents have full access to all messages they process." You'll quickly find out that this isn't the case. Rather, I should say they don't "easily" have full access rights to all the messages they process. In fact, strangely most of the properties of the message are read-only which posed some particular issues for our development. Luckily, we found a few workarounds that suited our needs for our environment.

You have two basic types of Transport Agents: Smtp Receive agents and Routing agents. A custom Smtp Receive agent will fire on incoming messages to the Smtp server while they would not fire on outgoing messages on our test environment (a single Exchange 2007 Server running in Hub Transport mode). A custom Routing Agent will fire after a Smtp Receive agent and on outgoing messages. Though I haven't proven this theory, I would also assume that a Smtp Receive agent would fire on messages transmitted to an Edge Transport Exchange 2007 server. You can find a list of available events your agent can call here: http://technet.microsoft.com/en-us/library/e7389d63-3172-40d5-bf53-0d7cd7e78340.aspx. You'll also notice from this page that Microsoft provides numerous built-in agents to handle various tasks.

One of the first snags I had in trying to get the sample agent from Technet running, was the Namespace. VB.NET does not behave in the same manner as C# when it comes to namespaces. In order to use the install command specified in the Technet article, I had to clear the root namespace:

Screen1

Another big snag we ran into was changing the MessageClass to the our custom form. Thankfully, Yuri from Microsoft was able to provide a workaround: http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=1381211&SiteID=17. I highly recommend using this forum as not only the MVP's but many of the MS product teams patrol with tons of helpful information.

Published Wednesday, April 04, 2007 2:23 PM by jeff
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Pete Yaniglos said:

I have written a transport agent for our Exchange 2007 environment and I am not able to locate to final pieces of data to have the complete solution was not sure if you could point me in the right direction.

1. Retrieve the text of the body.

2. I am able to redirect the message behind the scenes but would like to change the to address on the message so it displays properly in outlook.

I was able to both of these items with my 2003 Event Sink but have not been able to yet with c#.

Thanks.

August 8, 2007 9:11 AM
 

jeff said:

To get the body, use the args.MailItem.Message.Body.GetContentStreamRead method to get the Stream. You'll need to convert the message using the TextConverters classes. Also, be sure to make use of the args.MailItem.Message.Body.CharsetName String and the InputEncoding property of the TextConverter (you should be able to use Text.Encoding.GetEncoding(Message.Body.CharsetName)).

If you want to redirect the message, loop through the args.MailItem.Recipients collection and drop or add recipients as necessary. To change the address that Outlook sees, you'll need to loop through the args.MailItem.Message.To collection. This will add/remove it from the headers of the email.

August 24, 2007 3:25 PM
 

Christophe SAINCLIVIER said:

Hello,

I would like to write a transport agent which is able to modify the MAPI Message Class under certain conditions.

Is it possible ? if yes how ?

Thanks

September 6, 2007 11:05 AM
 

jeff said:

The MAPI Message Class is a ready only property in the Transport Agent. Yuri from MSFT had this workaround that worked for us:

http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=1381211&SiteID=17

October 1, 2007 2:04 PM
 

Romario said:

Could you tell me plz, how simply to receive message by agent, and then delete it, in other word, move it to Deleted Items folder?

December 12, 2007 9:19 AM
 

jeff said:

The transport agent gets the message before it ever reaches the storage interface. You can drop a message simply by clearing all recipients. If you would like to move the message to the user's Deleted Items folder, you probably need to look at using Exchange Web Services or the older Event Sink interface.

December 17, 2007 5:25 PM
 

Romario said:

Could you tell me plz how to move intercepted email ( by Transport Agent) to Junk-Folder? is it possible?

February 12, 2008 4:24 AM
 

Reinhard said:

I have written a transport agent which fires on the "End of Data Event". Then I would like to look if the recipient is already included in the users contact list, it the sender is not included already, I'd like to delete the message and send a message back to the sender with a link for verification ... How can I search the users contact list with C# ?

thanks in advance for your repsonse

May 21, 2008 4:13 PM
 

jeff said:

Romario: The transport agent knows nothing about the storage settings for the user. You would need to Exchange Web Services for this.

Reinhard: The same would apply here. You should be able to get the user's contact list from EWS and compare it against the message.

May 29, 2008 5:18 PM
 

Mark Adkins said:

Is it posible to write a transport rule that adds a catagory to the message?

September 11, 2008 9:14 AM
 

Mark Adkins said:

Is it posible to write a transport rule that adds a catagory to the message?

September 11, 2008 9:36 AM

Leave a Comment

(required) 
(optional)
(required) 
Submit

Powered by Community Server 2.1