Attachments disappear with custom email event handler
I was working with custom email event handler in SharePoint using SPEmailEventReceiver and found that when using the default functionality of I am able to configure and get the attachments to be added to the document library. Here is how the Incoming Email settings look like when you have your SharePoint server configured to receive emails and you enable your document library to receive emails.
I took the exact code that was provided in the MSDN documentation of SPEmailEventReceiver and implemented in my SharePoint site.
1: namespace Example_Namespace
2: {
3: public class Email_Handler: SPEmailEventReceiver
4: {
5: public override void EmailReceived(
6: SPList oList,
7: SPEmailMessage oMessage,
8: string strReceiverData)
9: {
10: SPListItem oListItem = oList.Items.Add();
11: oListItem["Title"] = oMessage.Headers["Subject"];
12: oListItem["Body"] = oMessage.HtmlBody;
13: oListItem.Update();
14: }
15: }
16: }
Now when I go to Incoming Email settings page for my Document library, here is what I see.
Where have all the settings gone?
Also when using the sample code from the MSDN article, I find that the attachments I am sending along with the email are not being captured in the document library. As my class is inheriting from SPEmailEventReceiver, my initial thought got me to that if I call base.EmailReceived in my event handler, then SharePoint should be able to handle the attachments and permission checks etc. But no, even calling base.EmailReceived did not resolve the problem.
This had me dive into checking what SharePoint does with the default settings and when I do not have my custom email event handler.
After some digging, found that SharePoint implement its own internal Email handler class which takes care of checking permissions, checking email settings for document library and adding the actual items to the list/library. EmailReceived function for SPEmailEventReceiver is a blank method with no definition. That is why calling "base.EmailReceived" method from class (inheriting from SPEmailEventReceiver) will have no effect.
Which lead to me investigating SPEmailMessage class (object of which is passed to EmailReceived method of your customer email event receiver). It has got Attachments property which contain all the attachments that are there in the email. Now things seems to be more in perspective and finally wrote the code to dump the attachments in the document library.
1: public override void EmailReceived( SPList list, SPEmailMessage message, string receiverData)
2: {
3: // Your rest of code to handle the different aspects of the email message received
4: // goes here. This would include permission check, duplicate items etc.
5: // After that, we will call the code to dump all the attachments in the root folder
6: foreach (SPEmailAttachment attachment in message.Attachments)
7: {
8: byte[] attachmentArray = new byte[attachment.ContentStream.Length];
9: attachment.ContentStream.Read(attachmentArray, 0, (int)attachment.ContentStream.Length);
10: list.RootFolder.Files.Add(attachment.FileName, attachmentArray);
11: }
12: }
Please note sample does not provide any functionality to check list settings for user permissions, duplicate files or saving the original email. This all this done by the default email handler for SharePoint. If you are planning to implement your own EmailHandler, you will need to take care of all the default functionality also provided by SharePoint.
Happy Coding…
-Manpreet
Comments
Anonymous
May 13, 2009
PingBack from http://asp-net-hosting.simplynetdev.com/attachments-disappear-with-custom-email-event-handler/Anonymous
June 02, 2009
So how did you get the emails that you sent to appear in the document library. What code did you add?Anonymous
June 02, 2009
The requirement in this case was to put the attachments from the email into the document library. The code given for the EmailReceived event handler in the post, will do exactly the same. If you also want to save the whole email message in the document library, you can use SPEmailMessage.GetMessageStream() method and save the stream as a .eml file in the document library.Anonymous
July 20, 2009
Hi, I'm kind of new to SharePoint EventHandlers. I've tried using the above code to pull the body message and subject into my SharePoint list. Before I install/deploy the eventhandler into the SharePoint document library, I am able to receive emails. But after I have install/deploy the eventhandler into the SharePoint, the document library did not even receive any email. Any idea on whats wrong? Please advice. Thanks. Regards, EugeneAnonymous
July 20, 2009
Hi, Previously I have posted here, but it seems that it did not display so i'm not sure if it was submitted. Anyways, I'd like to post again hoping to find a solution for this problem that I am stuck with. After I have installed the EventHandler with the above codes, it seems that it does not receive any more email in the document library. I'm really out of ideas on how to work around it or what is the problem. Please advice. Thank you so much.Anonymous
July 21, 2009
Hi Eguene, you would need to put a break point in your event handler and see if the event handler is actually being called and what is happening within the event handler. Let me know if that helps. Regards ManpreetAnonymous
July 22, 2009
Hi Manpreet, Thanks for the reply. I created the code using the 'Class Library' and I'm deploying the source code into a .dll file only. Therefore I don't think the breakpoint works here. Is there any other way I could test out the source code? Or if there are any templates that I could get from you to run with the code? My e-mail is 'eu.jen@hotmail.com'. I apologize for spamming your blog. I really appreciate your guidance. Regards, EugeneAnonymous
July 22, 2009
Hi Eugene, You can follow the debugging processes given at http://msdn.microsoft.com/en-us/library/dd206929.aspx or http://www.codeproject.com/KB/sharepoint/SharePoint-Debugging.aspx. These can help you understand how to debug your SharePoint code. Also ULS logs can give you pointers, if there are some errors in the code. -ManpreetAnonymous
July 27, 2009
Hey Manpreet, Sorry for the late reply, I've installed the debugger following the instructions given in the websites that you have referred me to. But I do not really know how to work it out. But from the Event Viewer -> Application this is the error that I got: -- Error loading and running event receiver getEmailBody.getEmail in emailBody, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bbcc0774720ac363. Additional information is below. : To add an item to a document library, use SPFileCollection.Add() -- But I have already loaded the assembly into the document folder. Any idea on whats wrong? Please advice. Thanks. -EugeneAnonymous
July 28, 2009
Hi Eugene, Send me your project and I can have a quick look. -ManpreetAnonymous
July 28, 2009
Hey Manpreet, Good news! I have found out that by using 'Announcement List' I could get all the details from the email. Previously I was using a document library which was a hassle. Thanks so much for your guidance and time. Hope to keep in touch with you in future. Will drop by your blog from time to time to learn more SharePoint stuffs. Great stuff you got here. :) -EugeneAnonymous
August 09, 2009
Hi All, The codes above works well, my issue is that I cannot retrieve the images included in the email message, I think the images is embedded within the email and I cannot find it (so that I can attach it to the list) using: "override EmailRevceived()". Also, I'm having trouble including the sender's active directory account in the [Created By] column of the Annoucements list. Does anyone have solutions to these issues? Thanks! -ErwinAnonymous
August 11, 2009
Hi Erwin, If the image is not an attachment in the email but is embedded, you would need to convert the email message to a MIME complaint object which can give you access to embeded resources. A sample MIME parser is available at http://mimeparser.codeplex.com/. I have not tested this but from description, it looks promising. You can get the raw feed of email message using SPEmailMessage.GetMessageStream method. To update the Created By column, you cannot just assign a value. You can get more details from Sowmyan's blog at http://blogs.msdn.com/sowmyancs/archive/2008/03/14/can-we-update-the-values-of-created-by-modified-by-columns-in-sharepoint-lists.aspx. Regards Manpreet AlagAnonymous
August 19, 2009
Hello Manpreet, Thanks for this solution, I've implemented it on my sharepoint server. Now I need some tips regarding the e-mails that are saved on the list. When ever I send a e-mail to the list, the field "created by" is filled with the value "System Account". Is there any way that I can solve this so the name that appears on the "created by" field is the same as the user that sent the e-mail? I'm trying to use impersonate programatically to solve this but with no luck yet. Do you have any tip for me.Anonymous
August 19, 2009
Hi Zacarias, You can follow the Sowmyan's blog at http://blogs.msdn.com/sowmyancs/archive/2008/03/14/can-we-update-the-values-of-created-by-modified-by-columns-in-sharepoint-lists.aspx to see how we can update the "Created By" column. You would ideally need to do this in the ItemAdded event, so that after the email has been added to the list, you can update the field value. More details on List Events available at http://msdn.microsoft.com/en-us/library/ms437502.aspx. -ManpreetAnonymous
September 23, 2009
The comment has been removedAnonymous
March 31, 2010
Hiya, Thanks for a gr8 blog. I have exactly similar requirement. We have a custom doc library defined based on custom list definition with custom columns. This doc library is based on a custom content type with fields of data types like: CHOICE, USER, DateTIME, MultiSelect. I managed to use your example and upload attachment to document library, but when I try to set properties of list item, it doesn't show my custom columns? any idea how i can do this? Am i missing something here?Anonymous
March 31, 2010
Hi Pryank, Are you able to see the columns in UI? If yes, then are you getting some error in the code when you try to update/access custom content type columns? If you are not able to see those columns when uploading a file using SharePoint's UI, then your list definition need to be checked. If the issue is with different type of columns, then this MSDN article can help you in understanding how to update different types of columns. http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.aspx -ManpreetAnonymous
June 13, 2010
Hi Manpreet, Thank you for blogging this solution. It takes a lot of the mystery out of the SPEmailEventReceiver. Is there a way to adapted this solution such that an MS Outlook message, along with its attachments, can be preserved in its original format and in its entirety within a document folder? The goal is to have users with MS Outlook simply click the document which then uses the client application to read the original email. Your knowledge and insight would be greatly appreciated. Cheers, DougAnonymous
December 15, 2010
Hi, Thanks for your effort put into this article. In fact attachments were easy to figure out. What I can't figure out is why the inline pictures disappear. If I attach a picture it is handled well, but if the picture is part of the message then it is lost. It is the same for jpg, gif, etc. Can you help with this issue? Thanks in advanceAnonymous
December 16, 2010
Hi Martin, If the image is not an attachment in the email but is embedded, you would need to convert the email message to a MIME complaint object which can give you access to embeded resources. A sample MIME parser is available at mimeparser.codeplex.com. I have not tested this but from description, it looks promising. You can get the raw feed of email message using SPEmailMessage.GetMessageStream method. -Manpreet Alag