One of the things that I was tasked with this past week was creating an app to help with email marketing. And before you ask, not spam... Well sort of spam, but it's internal to the company. Anyway, the application was to send nice, HTML formatted emails. One of the things they wanted though was embedded images within the email's text. Turns out, it's incredibly simple to do:
public class EmailSender : Message
{
#region Constructors
/// <summary>
/// Default Constructor
/// </summary>
public EmailSender()
{
Attachments = new List<Attachment>();
EmbeddedResources = new List<LinkedResource>();
Priority = MailPriority.Normal;
}
#endregion
#region Public Functions
/// <summary>
/// Sends an email
/// </summary>
/// <param name="Message">The body of the message</param>
public void SendMail(string Message)
{
try
{
Body = Message;
SendMail();
}
catch { throw; }
}
/// <summary>
/// Sends a piece of mail asynchronous
/// </summary>
/// <param name="Message">Message to be sent</param>
public void SendMailAsync(string Message)
{
try
{
Body = Message;
ThreadPool.QueueUserWorkItem(delegate { SendMail(); });
}
catch { throw; }
}
/// <summary>
/// Sends an email
/// </summary>
public void SendMail()
{
try
{
using (System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage())
{
char[] Splitter = { ',' };
string[] AddressCollection = To.Split(Splitter);
for (int x = 0; x < AddressCollection.Length; ++x)
{
message.To.Add(AddressCollection[x]);
}
if (!string.IsNullOrEmpty(CC))
{
AddressCollection = CC.Split(Splitter);
for (int x = 0; x < AddressCollection.Length; ++x)
{
message.CC.Add(AddressCollection[x]);
}
}
if (!string.IsNullOrEmpty(Bcc))
{
AddressCollection = Bcc.Split(Splitter);
for (int x = 0; x < AddressCollection.Length; ++x)
{
message.Bcc.Add(AddressCollection[x]);
}
}
message.Subject = Subject;
message.From = new System.Net.Mail.MailAddress((From));
AlternateView BodyView = AlternateView.CreateAlternateViewFromString(Body, null, MediaTypeNames.Text.Html);
foreach (LinkedResource Resource in EmbeddedResources)
{
BodyView.LinkedResources.Add(Resource);
}
message.AlternateViews.Add(BodyView);
//message.Body = Body;
message.Priority = Priority;
message.SubjectEncoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
message.BodyEncoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
message.IsBodyHtml = true;
foreach (Attachment TempAttachment in Attachments)
{
message.Attachments.Add(TempAttachment);
}
System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient(Server, Port);
if (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password))
{
smtp.Credentials = new System.Net.NetworkCredential(UserName, Password);
}
if (UseSSL)
smtp.EnableSsl = true;
else
smtp.EnableSsl = false;
smtp.Send(message);
}
}
catch { throw; }
}
/// <summary>
/// Sends a piece of mail asynchronous
/// </summary>
public void SendMailAsync()
{
try
{
ThreadPool.QueueUserWorkItem(delegate { SendMail(); });
}
catch { throw; }
}
#endregion
#region Properties
/// <summary>
/// Any attachments that are included with this
/// message.
/// </summary>
public List<Attachment> Attachments { get; set; }
/// <summary>
/// Any attachment (usually images) that need to be embedded in the message
/// </summary>
public List<LinkedResource> EmbeddedResources { get; set; }
/// <summary>
/// The priority of this message
/// </summary>
public MailPriority Priority { get; set; }
/// <summary>
/// Server Location
/// </summary>
public string Server { get; set; }
/// <summary>
/// User Name for the server
/// </summary>
public string UserName { get; set; }
/// <summary>
/// Password for the server
/// </summary>
public string Password { get; set; }
/// <summary>
/// Port to send the information on
/// </summary>
public int Port { get; set; }
/// <summary>
/// Decides whether we are using STARTTLS (SSL) or not
/// </summary>
public bool UseSSL { get; set; }
/// <summary>
/// Carbon copy send (seperate email addresses with a comma)
/// </summary>
public string CC { get; set; }
/// <summary>
/// Blind carbon copy send (seperate email addresses with a comma)
/// </summary>
public string Bcc { get; set; }
#endregion
}
The code above is a helper class from my utility library. In it there are fields for To, From, the SMTP server location, etc. The field we're interested in is EmbeddedResources. That field is a list of LinkedResource. A LinkedResource is exactly like the name says, a linked resource. An image, etc. that is attached to the email and usable within it. In order to use it, you must first tell it where to look for the image (new LinkedResource(ImageLocation)) and then set a content ID (the ContentId property) which is just a string name. Once that is set, you can link to it from inside your email. For example, if we set the ContentId to "MyImage", we can use it like this:
That's it. With that set as the body of our text and the LinkedResource added to our email, we're good. It doesn't work 100% on all systems (gmail seems to fail), but for most email apps (Outlook, etc.) it works rather well. Anyway, I personally can only think of one use for this but maybe I'm wrong. Maybe you're not going to use this for "marketing" purposes (ie spam). You never know. So try it out and happy coding.