HOWTO: Get Email Messages from Exchange to SharePoint
Many people ask about how to do this, so I thought I'd write up a sample. This sample basically searches the inbox of a user and then does an HTTP GET against the DAV:href to get the EML file and then does an HTTP PUT to upload it to a SharePoint document library.
using System;
using System.Web;
using System.Xml;
using System.Net;
using System.Text;
namespace UploadEmlToSharePoint
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
static System.Net.CredentialCache MyCredentialCache;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
System.Net.HttpWebRequest Request;
System.Net.WebResponse Response;
string strRootURI = "http://exchangeserver/exchange/User1/Inbox/";
string strSPSRootURI = "http://wss/Shared%20Documents/";
string strUserName = "User1";
string strPassword = "Passw0rd";
string strDomain = "DOMAIN";
string strQuery ="";
byte[] bytes = null;
System.IO.Stream RequestStream = null;
System.IO.Stream ResponseStream = null;
XmlDocument ResponseXmlDoc = null;
XmlNodeList ResponseNodes = null;
XmlNamespaceManager xmlnsm = new XmlNamespaceManager(new NameTable());
xmlnsm.AddNamespace("a","DAV:");
try
{
// Build the SQL query.
strQuery = "<?xml version=\"1.0\"?><D:searchrequest xmlns:D = \"DAV:\" >"
+ "<D:sql>SELECT \"DAV:displayname\" FROM \"" + strRootURI + "\""
+ "WHERE \"DAV:ishidden\" = false AND \"DAV:isfolder\" = false"
+ "</D:sql></D:searchrequest>";
// Create a new CredentialCache object and fill it with the network
// credentials required to access the server.
MyCredentialCache = new System.Net.CredentialCache();
MyCredentialCache.Add( new System.Uri(strRootURI),
"NTLM",
new System.Net.NetworkCredential(strUserName, strPassword, strDomain)
);
MyCredentialCache.Add(new System.Uri(strSPSRootURI),
"NTLM",
new System.Net.NetworkCredential(strUserName, strPassword, strDomain));
// Create the HttpWebRequest object.
Request = (System.Net.HttpWebRequest)HttpWebRequest.Create(strRootURI);
// Add the network credentials to the request.
Request.Credentials = MyCredentialCache;
// Specify the method.
Request.Method = "SEARCH";
// Encode the body using UTF-8.
bytes = Encoding.UTF8.GetBytes((string)strQuery);
// Set the content header length. This must be
// done before writing data to the request stream.
Request.ContentLength = bytes.Length;
//Set the translate header to false
Request.Headers.Add("Translate","f");
// Get a reference to the request stream.
RequestStream = Request.GetRequestStream();
// Write the SQL query to the request stream.
RequestStream.Write(bytes, 0, bytes.Length);
// Close the Stream object to release the connection
// for further use.
RequestStream.Close();
// Set the content type header.
Request.ContentType = "text/xml";
// Send the SEARCH method request and get the
// response from the server.
Response = (HttpWebResponse)Request.GetResponse();
// Get the XML response stream.
ResponseStream = Response.GetResponseStream();
// Create the XmlDocument object from the XML response stream.
ResponseXmlDoc = new XmlDocument();
ResponseXmlDoc.Load(ResponseStream);
ResponseNodes = ResponseXmlDoc.GetElementsByTagName("a:response");
if(ResponseNodes.Count > 0)
{
Console.WriteLine("Non-folder item hrefs...");
// Loop through the display name nodes.
for(int i=0; i<ResponseNodes.Count; i++)
{
// Display the non-folder item displayname.
XmlNode responseNode = ResponseNodes[i];
XmlNode hrefNode = responseNode.SelectSingleNode("a:href",xmlnsm);
XmlNode displayNameNode = responseNode.SelectSingleNode("a:propstat/a:prop/a:displayname",xmlnsm);
//Downloads the EML file from the specified URL
byte[] emlFile = GetBytesFrom(hrefNode.InnerText);
//Uploads the EML file to the SharePoint document library
UploadToSPS(emlFile,strSPSRootURI + System.Web.HttpUtility.UrlPathEncode(displayNameNode.InnerText));
}
}
else
{
Console.WriteLine("No non-folder items found...");
}
// Clean up.
ResponseStream.Close();
Response.Close();
}
catch(Exception ex)
{
// Catch any exceptions. Any error codes from the SEARCH
// method request on the server will be caught here, also.
Console.WriteLine(ex.Message);
}
Console.WriteLine("Done.");
Console.Read();
}
static byte[] GetBytesFrom(string DavURL)
{
Console.WriteLine(DavURL);
byte[] buffer;
System.Net.HttpWebRequest Request;
System.Net.HttpWebResponse Response;
System.IO.Stream ResponseStream;
Request = (HttpWebRequest)HttpWebRequest.Create(DavURL);
Request.Credentials = MyCredentialCache;
Request.Headers.Add("Translate","f");
Response = (HttpWebResponse)Request.GetResponse();
ResponseStream = Response.GetResponseStream();
buffer = new byte[Response.ContentLength];
ResponseStream.Read(buffer,0,(int)Response.ContentLength);
ResponseStream.Close();
Response.Close();
return buffer;
}
static void UploadToSPS(byte[] fileBytes, string URL)
{
Console.WriteLine("Uploading " + fileBytes.Length.ToString() + " bytes to " + URL);
System.Net.HttpWebRequest Request;
Request = (HttpWebRequest)HttpWebRequest.Create(URL);
Request.Credentials = MyCredentialCache;
Request.ContentLength = fileBytes.Length;
Request.Method = "PUT";
System.IO.Stream str = Request.GetRequestStream();
str.Write(fileBytes,0,fileBytes.Length);
str.Close();
Request.GetResponse();
}
}
}
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
Comments
Leave a Comment
About Patrick Creehan
Patrick Creehan is an Escalation Engineer in the Office Messaging Development team at Microsoft.