If you’re following Ty’s Office 365 Newswires and read this article about Microsoft already having sold five million Office 365 seats in roughly two and a half months, I’m sure you would agree with me that Office 365 is set to change, if not revolutionize the way people use and interact with Microsoft Office.
Of course this opens a whole world of possibilities to developers and even more so for the few, the proud Office developers. I love to dream up ways to integrate Microsoft Office with different applications and online services and in today’s post I’ll show you how to write a Microsoft Outlook Add-in that will save an e-mail’s attachments and/or the entire e-mail to an Office 365 hosted SharePoint Online list.
Let’s get started by creating a new ADX COM Add-in in Visual Studio 2010.

When prompted select Visual C# and Microsoft Office 2010.

This add-in will only be available in Microsoft Outlook so make sure it is the only selected application in the list of supported applications.

After completing the wizard, add a new ADXBackstageView component to the AddinModule designer surface and also add two ADXBackstageFastCommandButton controls. Set the following properties for the first button
- Name: adxButtonSaveAttachments
- Caption: Save Attachments to SharePoint Online
- InsertAfterIdMso : FileSaveAs
- Ribbons: OutlookMailRead
And set the following for the second button:
- Name: adxButtonSaveEmail
- Caption: Save E-mail to SharePoint Online
- InsertBeforeIdMso : SaveAttachments
- Ribbons: OutlookMailRead
With all the properties set, your design should resemble the following image:

When I first started with this article, I had the intention of uploading the files using the SharePoint Foundation 2010 Managed Client Object Model. Unfortunately, after numerous attempts and some further research I found it was just not as simple as the examples on that page indicated it should be. The problem is that when you need to access the SharePoint object from outside Office 365 or outside the browser, you need to use active authentication.
I’m not going to go into much detail about this, but I recommend you read Wictor Wilen’s article on this topic. I also based this example on the solution he suggested.
Ok, with that out of the way, let’s add the MSOnlineClaimsHelper.cs and WcfClientContracts.cs classes that Wictor wrote about (you can download the files from the article mentioned earlier, it is also available in this article’s sample project).
Next, we’ll add our own SharePointHelper.cs class. The code listing for this class is as follows:
using System;
using System.IO;
using System.Net;
using Microsoft.SharePoint.Client;
using Wictor.Office365;
namespace SaveToSharePoint
{
public class SharePointHelper
{
public string Username { get; set; }
public string Password { get; set; }
public string Url { get; set; }
public MsOnlineClaimsHelper ClaimsHelper { get; set; }
public SharePointHelper(string username, string password, string url)
{
this.Username = username;
this.Password = password;
this.Url = url;
this.ClaimsHelper = new MsOnlineClaimsHelper(url, username, password);
}
public HttpStatusCode UploadFile(string source, string destination)
{
using (ClientContext context = new ClientContext(this.Url))
{
//destination == "/Shared Documents/filename.extension"
string fileUrl = this.Url + destination;
FileStream fileStream = System.IO.File.OpenRead(source);
int dataLength = Convert.ToInt32(fileStream.Length);
byte[] data = new byte[dataLength];
fileStream.Read(data, 0, dataLength);
HttpWebRequest httpRequest =
HttpWebRequest.Create(fileUrl) as HttpWebRequest;
httpRequest.Method = "PUT";
httpRequest.Accept = "*/*";
httpRequest.ContentType = "multipart/form-data; charset=utf-8";
httpRequest.CookieContainer = this.ClaimsHelper.CookieContainer;
httpRequest.AllowAutoRedirect = false;
httpRequest.UserAgent =
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
httpRequest.Headers.Add("Accept-Language", "en-us");
httpRequest.Headers.Add("Translate", "F");
httpRequest.Headers.Add("Cache-Control", "no-cache");
httpRequest.ContentLength = fileStream.Length;
using (Stream stream = httpRequest.GetRequestStream())
{
stream.Write(data, 0, dataLength);
}
HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
return response.StatusCode;
}
}
}
}
Save the class and switch back to the AddinModule designer and select the BackstageView component we’ve added earlier. Select the “Save Attachments to SharePoint Online” button and add an event handler for its OnClick event. Add the following code to the event handler:
private void adxButtonSaveAttachments_OnClick(object sender, IRibbonControl control)
{
Outlook.Inspector currInspector = null;
Outlook.MailItem currMail = null;
Outlook.Attachments attachments = null;
int numberOfAttachments = 0;
Dictionary<string , string> files = new Dictionary<string , string>();
SharePointHelper spHelper = null;
try
{
currInspector = OutlookApp.ActiveInspector();
if (currInspector.CurrentItem is Outlook.MailItem)
{
currMail = (Outlook.MailItem)currInspector.CurrentItem;
attachments = currMail.Attachments;
numberOfAttachments = attachments.Count;
if (numberOfAttachments > 0)
{
spHelper = new SharePointHelper(
"your@email.com",
"YourPassword",
"https://yourdomain.sharepoint.com/sites/TeamSite");
for (int i = 1; i < = numberOfAttachments; i++)
{
Outlook.Attachment attachment = attachments[i];
string filePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
attachment.FileName);
attachment.SaveAsFile(filePath);
files.Add(attachment.FileName, filePath);
Marshal.ReleaseComObject(attachment);
}
foreach (var file in files)
{
System.Net.HttpStatusCode status =
spHelper.UploadFile(file.Value, "/Shared Documents/" + file.Key);
if (status != System.Net.HttpStatusCode.Created)
MessageBox.Show(file.Key + " failed to upload.");
}
}
}
}
finally
{
if (attachments != null)
Marshal.ReleaseComObject(attachments);
if (currMail != null)
Marshal.ReleaseComObject(currMail);
if (currInspector != null)
Marshal.ReleaseComObject(currInspector);
}
MessageBox.Show("Done");
}
This code will check whether the current open e-mail has attachments and then save those attachments to the Shared Documents library in SharePoint.
Next, add an event handler for the “Save E-mail to SharePoint Online” button and add the following code to it:
private void adxButtonSaveEmail_OnClick(object sender, IRibbonControl control)
{
Outlook.Inspector currInspector = null;
Outlook.MailItem currMail = null;
SharePointHelper spHelper = null;
string fileName = string.Empty;
try
{
currInspector = OutlookApp.ActiveInspector();
if (currInspector.CurrentItem is Outlook.MailItem)
{
spHelper = new SharePointHelper(
"your@email.com",
"YourPassword",
"https://yourdomain.sharepoint.com/sites/TeamSite");
currMail = (Outlook.MailItem)currInspector.CurrentItem;
fileName = String.Format(
"{0} - {1}.msg",
SafeFileName(currMail.SenderName),
SafeFileName(currMail.Subject));
string filePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
fileName);
currMail.SaveAs(filePath, Outlook.OlSaveAsType.olMSG);
System.Net.HttpStatusCode status =
spHelper.UploadFile(filePath, "/Shared Documents/" + fileName);
if (status != System.Net.HttpStatusCode.Created)
MessageBox.Show(fileName + " failed to upload.");
}
}
finally
{
if (currMail != null)
Marshal.ReleaseComObject(currMail);
if (currInspector != null)
Marshal.ReleaseComObject(currInspector);
}
MessageBox.Show("Done");
}
This code essentially does the same as the previous listing, except that instead of only saving the e-mail’s attachments it will save the entire e-mail to the SharePoint library.
Build, register and run your project and open an e-mail in Outlook that has attachments.

When you click on the File Menu you should see the two buttons we’ve added earlier:

Click on the “Save Attachment to SharePoint Online” button. It should take a few seconds and when you view the Shared Documents library in SharePoint you should see all the files that was attached to the e-mail.

Finally, click on the “Save E-mail to SharePoint Online” button. The entire e-mail should now be saved in the Shared Documents library.

Thank you for reading. Until next time, keep coding!
Available downloads:
The sample COM Add-in was developed using Add-in Express for Office and .NET:





