SharePoint: How to embed image of article page in email body

I had a requirement to share/email an article for specified users after content owner approval and publish. To get this functionality, added a workflow to the article pages to send out email to the specified users of the published article. In workflow, wrote code to retrieve the page content and rollup image  properties of article, prepared html body with these properties and send email. Deployed solution and attached workflow to the pages library. Started testing article email/share functionality, received email successfully and got "X" or no image icon in the email body. I tried couple of methods to bring this functionality and finally succeeded with below sample code.

Tried below sample in console application.

 1) First get the site and web object of Pages library

using (SPSite site = new SPSite("https://sharepointweb/sites/rootsitecollection"))
{
  using (SPWeb web = site.OpenWeb())
  {
     SPList lst = web.Lists["Pages"];
     SPListItem itm = lst.GetItemById(1); // 1 = ID of the published news article
  1. Get the image of article page and append with Site URL to get the image from SharePoint image library
ImageFieldValue currentFieldValue = itm["PublishingRollupImage"] as  ImageFieldValue;
string imageURL = currentFieldValue.ImageUrl; // Url of the article image
string baseURL = site.Url.Replace(site.ServerRelativeUrl,  ""); // Site URL
string imageFullURL = baseURL + imageURL; // Ex: https://sharepointweb/sites/rootsitecollection/PublishingImages/sharepoint.jpg
  1. Now image URL is ready, get the image from publishing image library and store in memory stream object.
SPFile file = web.GetFile(imageFullURL);
Byte[] fileContentsArray = null;
MemoryStream imageStream = null;
using (Stream fileContents = file.OpenBinaryStream())
{
    long length = fileContents.Length;
    fileContentsArray = new  Byte[length];
    fileContents.Read(fileContentsArray, 0, Convert.ToInt32(length));
}
imageStream = new  MemoryStream(fileContentsArray);
  
Uri imageURI = null;
if (!Uri.TryCreate(imageURL, UriKind.Absolute, out imageURI))
    Uri.TryCreate(new Uri(baseURL), imageURL, out imageURI);

4)  Create a LinkedResource object, this object contains binary data of the Image. This binary data is encoded as part of the email, and sent along as part of the MailMessage. Give the LinkedResource a unique name, also known as CID (or Content-ID).

string imageName = Guid.NewGuid().ToString().Replace("-", string.Empty);
  
LinkedResource imagelink = new  LinkedResource(imageStream, "image/jpeg");                   
imagelink.ContentId = imageName;
imagelink.ContentLink = new  Uri("cid:" + imageName);
imagelink.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
  
imgHTML = imgHTML.Replace(imageURL, "cid:" + imageName);

5) Create a HTML AlternateView, and add rollup image <img> tag.



      string htmlBOdy = "<html><body><div>" + imgHTML + "</div><div>TODO: Add page content/description</div></body></html>";
              
      AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBOdy,     null    ,     "text/html"    );  
      htmlView.LinkedResources.Add(imagelink);  
  1. All set to getting image and embedding as CID inline image and placing in alternate view. 


      string from = site.WebApplication.OutboundMailSenderAddress;
      string smtpAddress = site.WebApplication.OutboundMailServiceInstance.Server.Address;
              
      // Assign SMTP address  
      SmtpClient smtpClient =     new  SmtpClient();
      smtpClient.Host = smtpAddress;  
              
      MailMessage mailMessage =     new  MailMessage(from, "raj@sharepoint.com");
      mailMessage.Subject =     "how to embed image of article page"    ;  
              
      // Add the Alternate view with the Mail message  
      mailMessage.AlternateViews.Add(htmlView);  
      mailMessage.IsBodyHtml =     true    ;  
              
      smtpClient.Send(mailMessage);  
  1. Close brackets and you are good to send an email
  }
}

Hope this TechNet wiki will help some one or save their time.