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 = "https://exchangeserver/exchange/User1/Inbox/";             string strSPSRootURI = "https://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();
}
}
}