I found this amazing editor at http://summernote.org that accepts copy paste of images. I was looking for such editor to avoid re-inventing the wheel so that it can be used for an email application. This fits well and it is easy to use too. First, you may download the summernote editor here.
Lets implement summernote editor first.
1. link the js and css file.
2. Add the editor textarea tag.
3. Convert it to Summernote Editor
4. Now the editor will looks like this;
5. Now you can use this as a standard email editor page that support HTML for the body. Even this editor support copy paste of images. But it uses Base64 encoding that is not understood by most browsers and email clients as valid inline images. So you will notice the red cross marks that says no valid images attached to the body.
6. To avoid this, We can write an email handler class. We discussed one here and lets modify it to cater the Base64 Encoded images. The following is a public class that you can use to send emails.
7. Call this class as below to send email.
8. There is no 8th step. This is it. Try it in your application and copy paste the images to body as you wish and send as inline attachments.
Happy coding... And if any issue, just comment.
Lets implement summernote editor first.
1. link the js and css file.
<link href="/script/summernote/summernote.css" rel="stylesheet" type="text/css" />
<script src="/script/summernote/summernote.js" type="text/javascript"></script>
2. Add the editor textarea tag.
<textarea id="txtSNBody" name="txtDescriptionIE9" runat="server" rows="15" cols="80" clientidmode="Static" style="width: 100%"></textarea>
3. Convert it to Summernote Editor
var f = jQuery.noConflict(); // To avoid JQuery conflict
f(document).ready(function () {
f('#txtSNBody').summernote({
height: 300, // set editor height
minHeight: null, // set minimum height of editor
maxHeight: null,
width: 150, // set width
toolbar: [
// [groupName, [list of button]]
['Insert', ['picture', 'link', 'video', 'table', 'hr', 'style', 'ol', 'ul', 'paragraph', 'height', 'fullscreen', 'codeview', 'undo', 'redo', 'help']],
['style', ['fontname', 'fontsize', 'color', 'bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'clear']]
],
defaultFontName: 'Arial',
callbacks: {
onKeyup: function (e) {
DrafttxtSNBody(f('#txtSNBody').summernote('code')); // This function saves the email as a draft asynchronously using jquery ajax
}
}
});
f('.note-toolbar').css('font-size', '11px'); // Set toolbar font size
});
4. Now the editor will looks like this;
(The content is blurred using a photo editor)
5. Now you can use this as a standard email editor page that support HTML for the body. Even this editor support copy paste of images. But it uses Base64 encoding that is not understood by most browsers and email clients as valid inline images. So you will notice the red cross marks that says no valid images attached to the body.
6. To avoid this, We can write an email handler class. We discussed one here and lets modify it to cater the Base64 Encoded images. The following is a public class that you can use to send emails.
public class EmailHelper
{
private MailMessage Message = null;
private SmtpClient smtpClient = null;
public MailAddress FromAddress { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public bool has64BaseImages { get; set; }
public EmailHelper()
{
smtpClient = new SmtpClient();
smtpClient.Host = ConfigurationManager.AppSettings["smtpHost"];
smtpClient.UseDefaultCredentials = false;
//smtpClient.EnableSsl = true; // Enable this if SSL is needed
smtpClient.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["userName"], ConfigurationManager.AppSettings["password"]);
smtpClient.Port = Convert.ToInt32(ConfigurationManager.AppSettings["port"]);
Message = new MailMessage();
}
public EmailHelper(string host, int port, string userName, string password, bool ssl)
: this()
{
smtpClient.Host = host;
smtpClient.Port = port;
smtpClient.EnableSsl = ssl;
smtpClient.Credentials = new NetworkCredential(userName, password);
}
public void AddToAddress(string email, string name = null)
{
if (!string.IsNullOrEmpty(email))
{
email = email.Replace(",", ";");
string[] emailList = email.Split(';');
for (int i = 0; i < emailList.Length; i++)
{
if (!string.IsNullOrEmpty(emailList[i]))
Message.To.Add(new MailAddress(emailList[i].Trim(), name));
}
}
}
public void AddCcAddress(string email, string name = null)
{
if (!string.IsNullOrEmpty(email))
{
email = email.Replace(",", ";");
string[] emailList = email.Split(';');
for (int i = 0; i < emailList.Length; i++)
{
if (!string.IsNullOrEmpty(emailList[i]))
Message.CC.Add(new MailAddress(emailList[i].Trim(), name));
}
}
}
public void AddBccAddress(string email, string name = null)
{
if (!string.IsNullOrEmpty(email))
{
email = email.Replace(",", ";");
string[] emailList = email.Split(';');
for (int i = 0; i < emailList.Length; i++)
{
if (!string.IsNullOrEmpty(emailList[i]))
Message.Bcc.Add(new MailAddress(emailList[i].Trim(), name));
}
}
}
public void AddAttachment(string file, string mimeType)
{
Attachment attachment = new Attachment(file, mimeType);
Message.Attachments.Add(attachment);
}
public void AddAttachment(Attachment objAttachment)
{
Message.Attachments.Add(objAttachment);
}
public void SendMail()
{
try
{
string imgTempFolder = new Random().Next().ToString();
string imgSavePath = HttpContext.Current.Server.MapPath(@"~\App_Code\GBL\EmailHelper\" + imgTempFolder + @"\"); // You can have your own path
string msg = "<html><body>" + Body + "</html></body>";
foreach (Match m in Regex.Matches(msg, "<img.+?src=[\"'](.+?)[\"'].+?>", RegexOptions.IgnoreCase | RegexOptions.Multiline))
{
string src = m.Groups[1].Value;
if (src.StartsWith("data:image/png;base64"))
{
has64BaseImages = true;
break;
}
}
if (has64BaseImages) // If Base64 found let them attach as LinkedResources
{
if (!Directory.Exists(imgSavePath))
Directory.CreateDirectory(imgSavePath);
Dictionary<int, string> dicImgs = new Dictionary<int, string>();
Dictionary<int, LinkedResource> dicImgLR = new Dictionary<int, LinkedResource>();
int c = 1;
foreach (Match m in Regex.Matches(msg, "<img.+?src=[\"'](.+?)[\"'].+?>", RegexOptions.IgnoreCase | RegexOptions.Multiline))
{
string src = m.Groups[1].Value;
if (!src.StartsWith("data:image/png;base64"))
continue;
int i = new Random().Next();
byte[] bytes = Convert.FromBase64String(src.Split(',')[1]);
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
image.Save(imgSavePath + i.ToString() + ".png");
dicImgs.Add(c, imgSavePath + i.ToString() + ".png");
string mediaType = MediaTypeNames.Image.Jpeg;
LinkedResource ilImg = new LinkedResource(imgSavePath + i.ToString() + ".png");
ilImg.ContentId = c.ToString();
ilImg.ContentType.MediaType = mediaType;
ilImg.TransferEncoding = TransferEncoding.Base64;
ilImg.ContentType.Name = ilImg.ContentId;
ilImg.ContentLink = new Uri("cid:" + ilImg.ContentId);
dicImgLR.Add(c, ilImg);
src = src.Replace(src, "cid:" + c);
c++;
}
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(msg, Encoding.UTF8, MediaTypeNames.Text.Html);
foreach (var item in dicImgLR)
{
htmlView.LinkedResources.Add(item.Value);
}
Message.AlternateViews.Add(htmlView);
}
if (FromAddress == null || (FromAddress != null && FromAddress.Address.Equals("")))
{
throw new Exception("From address not defined");
}
else
{
if (string.IsNullOrEmpty(FromAddress.DisplayName))
FromAddress = new MailAddress(FromAddress.Address, string.Empty);
Message.From = FromAddress;
}
if (Message.To.Count <= 0)
{ throw new Exception("To address not defined"); }
Message.Subject = Subject;
Message.IsBodyHtml = true;
if (!has64BaseImages)
Message.Body = Body;
Message.BodyEncoding = Encoding.UTF8;
Message.SubjectEncoding = Encoding.UTF8;
smtpClient.Send(Message);
}
catch (Exception)
{
throw new Exception("Email failed to send");
}
}
public static string GetFileMimeType(string fileName)
{
string fileExt = Path.GetExtension(fileName.ToLower());
string mimeType = string.Empty;
switch (fileExt)
{
case ".htm":
case ".html":
mimeType = "text/html";
break;
case ".xml":
mimeType = "text/xml";
break;
case ".jpg":
case ".jpeg":
mimeType = "image/jpeg";
break;
case ".gif":
mimeType = "image/gif";
break;
case ".png":
mimeType = "image/png";
break;
case ".bmp":
mimeType = "image/bmp";
break;
case ".pdf":
mimeType = "application/pdf";
break;
case ".doc":
mimeType = "application/msword";
break;
case ".docx":
mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
break;
case ".xls":
mimeType = "application/x-msexcel";
break;
case ".xlsx":
mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
break;
case ".csv":
mimeType = "application/csv";
break;
case ".ppt":
mimeType = "application/vnd.ms-powerpoint";
break;
case ".pptx":
mimeType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
break;
case ".rar":
mimeType = "application/x-rar-compressed";
break;
case ".zip":
mimeType = "application/x-zip-compressed";
break;
default:
mimeType = "text/plain";
break;
}
return mimeType;
}
}
7. Call this class as below to send email.
EmailHelper emailHelper = new EmailHelper();
emailHelper.FromAddress = new System.Net.Mail.MailAddress("From@domain.com");
emailHelper.AddToAddress("To@domain.com");
emailHelper.AddCcAddress("Cc@domain.com");
emailHelper.AddCcAddress("Bcc@domain.com");
emailHelper.AddBccAddress(txtEmailBcc.Text.Trim());
emailHelper.AddAttachment("FilePath", EmailHelper.GetFileMimeType(item.Value.Value));
emailHelper.Subject = "Subject";
msgBody = txtEmailBody.InnerText.Trim(); // The summernote editor
emailHelper.Body = msgBody;
emailHelper.SendMail();
8. There is no 8th step. This is it. Try it in your application and copy paste the images to body as you wish and send as inline attachments.
Happy coding... And if any issue, just comment.
Do you have the source code for it? , I can send the embedded image but i could not send the message.body together with embedded image
ReplyDeleteDid you try the above code? Copy it and try and let me know.
Delete