0

I have created a class called Mailer for sending Image Enabled Email through my asp.net web application 4.0.

Here is my code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Linq;
using System.Xml;
using System.Net.Mail;
using System.Net.Mime;
using System.IO;
/// <summary>
/// Summary description for Mailer
/// </summary>
namespace MyNameSpace
{
    public class Mailer
    {
        #region Constructeurs
        public Mailer()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        public Mailer(string sSmtp, string sPort, string sFrom, string sTo, string sSubject, string sCc, string sBcc, string sBodyHtml, List<string> sFileNames)
        {
            this.Smtp = sSmtp;
            this.Port = sPort;
            this.From = sFrom;
            this.To = sTo;
            this.Subject = sSubject;
            this.Cc = sCc;
            this.Bcc = sBcc;
            this.BodyHtml = sBodyHtml;
            this.FileNames = sFileNames;
        }
        #endregion

        MailMessage Message = new MailMessage();
        SmtpClient SmtpMail = new SmtpClient();

        #region Champs publics
        string _sSmtp;
        ///
        /// Serveur smtp
        ///
        public string Smtp
        {
            get { return _sSmtp; }
            set { _sSmtp = value; }
        }
        string _sPort;
        ///
        /// Serveur Port
        ///
        public string Port
        {
            get { return _sPort; }
            set { _sPort = value; }
        }
        string _sFrom;
        ///
        /// Adresse d’envoi
        ///
        public string From
        {
            get { return _sFrom; }
            set { _sFrom = value; }
        }
        string _sTo;
        ///
        /// Destinataire du mail
        ///
        public string To
        {
            get { return _sTo; }
            set { _sTo = value; }
        }
        string _sSubject;
        ///
        /// Sujet du mail
        ///
        public string Subject
        {
            get { return _sSubject; }
            set { _sSubject = value; }
        }
        // Mail CC
        string _sCc;
        public string Cc
        {
            get { return _sCc; }
            set { _sCc = value; }
        }
        // Mail Bcc
        string _sBcc;
        public string Bcc
        {
            get { return _sBcc; }
            set { _sBcc = value; }
        }
        string _sBodyHtml;
        ///
        /// Mail html body
        ///
        public string BodyHtml
        {
            get { return _sBodyHtml; }
            set { _sBodyHtml = value; }
        }
        List<string> _sFileNames;
        public List<string> FileNames
        {
            get { return _sFileNames; }
            set { _sFileNames = value; }
        }
        #endregion
        public void SendHtmlMail()
        {
            this.Message.IsBodyHtml = true;
            this.Message.From = new MailAddress(this.From);
            this.Message.Sender = new MailAddress(this.From);
            if (this.To.Contains(","))
            {
                string[] values1 = To.Split(',');
                for (int i = 0; i < values1.Length; i++)
                {
                    values1[i] = values1[i].Trim();
                }
                foreach (var item1 in values1)
                {
                    this.Message.To.Add(new MailAddress(item1.ToString()));
                }
            }
            else
            {
                this.Message.To.Add(new MailAddress(this.To));
            }
            if (!string.IsNullOrEmpty(this.Cc))
            {
                if (this.Cc.Contains(","))
                {
                    string[] values2 = this.Cc.Split(',');
                    for (int i = 0; i < values2.Length; i++)
                    {
                        values2[i] = values2[i].Trim();
                    }
                    foreach (var item2 in values2)
                    {
                        this.Message.CC.Add(new MailAddress(item2.ToString()));
                    }
                }
                else
                {
                    this.Message.CC.Add(new MailAddress(this.Cc));
                }
            }
            if (!string.IsNullOrEmpty(this.Bcc))
            {
                if (this.Bcc.Contains(","))
                {
                    string[] values3 = this.Bcc.Split(',');
                    for (int i = 0; i < values3.Length; i++)
                    {
                        values3[i] = values3[i].Trim();
                    }
                    foreach (var item3 in values3)
                    {
                        this.Message.Bcc.Add(new MailAddress(item3.ToString()));
                    }
                }
                else
                {
                    this.Message.Bcc.Add(new MailAddress(this.Bcc));
                }
            }
            this.Message.Subject = this.Subject;

            //– Message Text/Html–//
            AlternateView alternateHtml = GetAlternateViewLinkedResources(this.BodyHtml);
            this.Message.AlternateViews.Add(alternateHtml);
            this.SmtpMail.Host = this.Smtp;

            using (DataClassesDataContext db = new DataClassesDataContext())
            {
                for (int i = 0; i < this.FileNames.Count; i++)
                {
                    Attachment mailAttachment = new Attachment(Path.Combine(HttpRuntime.AppDomainAppPath, "EmailFiles/" + db.Files.Where(f => f.File_name.Equals(FileNames[i].Substring(0, 15))).Select(f => f.File_name + f.File_ext).SingleOrDefault().ToString()));
                    this.Message.Attachments.Add(mailAttachment);
                }
            }
            this.SmtpMail.Send(this.Message);
        }
        ///
        /// Return AlternateView object with Linked resources
        ///
        ///
        ///
        private AlternateView GetAlternateViewLinkedResources(string sHtmlMessage)
        {
            XmlDocument oXml = new XmlDocument();
            //Return the resources XML datas
            oXml = EmbedHtmlImage(sHtmlMessage);
            //Make the replace un html body
            foreach (XmlNode oNode in oXml.SelectNodes(HttpContext.Current.Server.MapPath("~/EmailImages/")))
            {
                sHtmlMessage = sHtmlMessage.Replace(oNode.Attributes.GetNamedItem("src").Value.ToString(), oNode.Attributes.GetNamedItem("cid").Value.ToString());
            }
            AlternateView oAlternateHtml = AlternateView.CreateAlternateViewFromString(sHtmlMessage, System.Text.Encoding.UTF8, MediaTypeNames.Text.Html);
            //Add linked resources
            foreach (XmlNode oNode in oXml.SelectNodes(HttpContext.Current.Server.MapPath("~/EmailImages/")))
            {
                LinkedResource oResource = null;//new LinkedResource(oNode.Attributes.GetNamedItem(“src”).Value.ToString());
                sHtmlMessage = sHtmlMessage.Replace(oNode.Attributes.GetNamedItem("src").Value.ToString(), oNode.Attributes.GetNamedItem("cid").Value.ToString());
                switch (oNode.Attributes.GetNamedItem("imagetype").Value.ToString())
                {
                    case "gif":
                        oResource = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath(oNode.Attributes.GetNamedItem("src").Value.ToString()), System.Net.Mime.MediaTypeNames.Image.Gif);
                        break;
                    case "jpg":
                        oResource = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath(oNode.Attributes.GetNamedItem("src").Value.ToString()), System.Net.Mime.MediaTypeNames.Image.Jpeg);
                        break;
                    case "tiff":
                        oResource = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath(oNode.Attributes.GetNamedItem("src").Value.ToString()), System.Net.Mime.MediaTypeNames.Image.Tiff);
                        break;
                }
                oResource.ContentId = oNode.Attributes.GetNamedItem("uid").Value.ToString();
                //To refer to this image in the html body, use
                oAlternateHtml.LinkedResources.Add(oResource);
            }
            return oAlternateHtml;
        }

        private XmlDocument EmbedHtmlImage(string sHtmlBody)
        {
            string sNewHtmlBody = sHtmlBody;
            string sNewGuid = string.Empty;
            string sSrcAttribute = string.Empty;
            int iStartImageSrcAttribute = 0;
            int iEndImageSrcAttribute = 0;
            int iEndImageTag = 0;
            //Detect if email contain image html tag, i have choose to use XmlDocument for my convenience
            XmlDocument oXml = new XmlDocument();
            oXml.LoadXml(@"");
            Int32 iStartImageTag = sNewHtmlBody.IndexOf("", iEndImageSrcAttribute);

            XmlNode oNode;
            XmlAttribute oAtt;
            if (CheckExtension(sNewHtmlBody, iStartImageSrcAttribute + 5, (iEndImageSrcAttribute - (iStartImageSrcAttribute + 5))))
            {
                sSrcAttribute = sNewHtmlBody.Substring(iStartImageSrcAttribute + 5, (iEndImageSrcAttribute - (iStartImageSrcAttribute + 5)));
                oNode = oXml.CreateNode(XmlNodeType.Element, "image", "");
                oAtt = oXml.CreateAttribute("fulltag");
                oAtt.Value = sNewHtmlBody.Substring(iStartImageTag, (iEndImageTag - iStartImageTag) + 1);
                oNode.Attributes.Append(oAtt);
                oAtt = oXml.CreateAttribute("src");
                oAtt.Value = sSrcAttribute;
                oNode.Attributes.Append(oAtt);

                sNewGuid = Guid.NewGuid().ToString();
                oAtt = oXml.CreateAttribute("uid");
                oAtt.Value = sNewGuid;
                oNode.Attributes.Append(oAtt);

                oAtt = oXml.CreateAttribute("cid");
                oAtt.Value = "cid:" + sNewGuid;
                oNode.Attributes.Append(oAtt);
                oAtt = oXml.CreateAttribute("imagetype");
                if (sSrcAttribute.ToLower().EndsWith("jpg"))
                {
                    oAtt.Value = "jpg";
                }
                if (sSrcAttribute.ToLower().EndsWith("gif"))
                {
                    oAtt.Value = "gif";
                }
                if (sSrcAttribute.ToLower().EndsWith("tiff"))
                {
                    oAtt.Value = "tiff";
                }
                oNode.Attributes.Append(oAtt);

                //Add xml node to root
                oXml.SelectSingleNode("/EasyMail_New").AppendChild(oNode);
            }

            while (iStartImageTag < sNewHtmlBody.LastIndexOf(@"<img"))
            {
                iStartImageTag = sNewHtmlBody.IndexOf("", iEndImageSrcAttribute);

                //Evite les doublons
                XmlNode oExistNode = oXml.SelectSingleNode(@"/EasyMail_New/EmailImages[@src = '" + sNewHtmlBody.Substring(iStartImageSrcAttribute + 5, (iEndImageSrcAttribute - (iStartImageSrcAttribute + 5))) + @"']");
                if (oExistNode == null)
                {
                    if (CheckExtension(sNewHtmlBody, iStartImageSrcAttribute + 5, (iEndImageSrcAttribute - (iStartImageSrcAttribute + 5))))
                    {
                        sSrcAttribute = sNewHtmlBody.Substring(iStartImageSrcAttribute + 5, (iEndImageSrcAttribute - (iStartImageSrcAttribute + 5)));
                        oNode = oXml.CreateNode(XmlNodeType.Element, "image", "");
                        oAtt = oXml.CreateAttribute("fulltag");
                        oAtt.Value = sNewHtmlBody.Substring(iStartImageTag, (iEndImageTag - iStartImageTag) + 1);
                        oNode.Attributes.Append(oAtt);

                        oAtt = oXml.CreateAttribute("src");
                        oAtt.Value = sSrcAttribute;
                        oNode.Attributes.Append(oAtt);
                        //Generation du Guid
                        sNewGuid = Guid.NewGuid().ToString();
                        oAtt = oXml.CreateAttribute("uid");
                        oAtt.Value = sNewGuid;
                        oNode.Attributes.Append(oAtt);

                        oAtt = oXml.CreateAttribute("cid");
                        oAtt.Value = "cid:" + sNewGuid;
                        oNode.Attributes.Append(oAtt);

                        oAtt = oXml.CreateAttribute("imagetype");
                        if (sSrcAttribute.ToLower().EndsWith("jpg"))
                        {
                            oAtt.Value = "jpg";
                        }
                        if (sSrcAttribute.ToLower().EndsWith("gif"))
                        {
                            oAtt.Value = "gif";
                        }
                        if (sSrcAttribute.ToLower().EndsWith("tiff"))
                        {
                            oAtt.Value = "tiff";
                        }
                        oNode.Attributes.Append(oAtt);
                        //Add xml node to root
                        oXml.SelectSingleNode("/EasyMail_New").AppendChild(oNode);
                    }
                }
            }

            return oXml;
        }

        private Boolean CheckExtension(string sNewHtmlBody, Int32 iBegin, Int32 iLength)
        {
            Boolean bRes = false;
            bRes = (sNewHtmlBody.Substring(iBegin, iLength).ToLower().EndsWith(".gif")) ? true : bRes;
            bRes = (sNewHtmlBody.Substring(iBegin, iLength).ToLower().EndsWith(".jpg")) ? true : bRes;
            bRes = (sNewHtmlBody.Substring(iBegin, iLength).ToLower().EndsWith(".tiff")) ? true : bRes;
            return bRes;
        }
    }
}

I am calling it from pages like this:

Mailer myMail = new Mailer(Host, Port, Email, (touser1 == ',') ? ToUser.TrimEnd(',') : ToUser, txt_ComName.Text.Trim(), (cc1 == ',') ? Cc.TrimEnd(',') : Cc, (bcc1 == ',') ? Bcc.TrimEnd(',') : Bcc, sbody, file_names.ToList());
                                    myMail.SendHtmlMail();

At runtime I get this error :

Server Error in '/EasyMail_New' Application.

Root element is missing.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Xml.XmlException: Root element is missing.

Source Error: 


Line 241:            //Detect if email contain image html tag, i have choose to use XmlDocument for my convenience
Line 242:            XmlDocument oXml = new XmlDocument();
Line 243:            oXml.LoadXml(@"");
Line 244:            Int32 iStartImageTag = sNewHtmlBody.IndexOf("", iEndImageSrcAttribute);
Line 245:

Source File: e:\Shalin\WorkMaterial\EasyMail_New\App_Code\Mailer.cs    Line: 243 

Stack Trace: 


[XmlException: Root element is missing.]
   System.Xml.XmlTextReaderImpl.Throw(Exception e) +73
   System.Xml.XmlTextReaderImpl.ParseDocumentContent() +4076618
   System.Xml.XmlTextReaderImpl.Read() +145
   System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace) +114
   System.Xml.XmlDocument.Load(XmlReader reader) +114
   System.Xml.XmlDocument.LoadXml(String xml) +168
   MyNameSpace.Mailer.EmbedHtmlImage(String sHtmlBody) in e:\Shalin\WorkMaterial\EasyMail_New\App_Code\Mailer.cs:243
   MyNameSpace.Mailer.GetAlternateViewLinkedResources(String sHtmlMessage) in e:\Shalin\WorkMaterial\EasyMail_New\App_Code\Mailer.cs:202
   MyNameSpace.Mailer.SendHtmlMail() in e:\Shalin\WorkMaterial\EasyMail_New\App_Code\Mailer.cs:179
   _Default.submit_Click(Object sender, EventArgs e) in e:\Shalin\WorkMaterial\EasyMail_New\Mail.aspx.cs:1303
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
3
  • 1
    here i this artile useful for me.. Commented Feb 23, 2015 at 12:04
  • Why we should read all your code to find how to change it? Please create a simple runnable example. Commented Feb 23, 2015 at 12:42
  • I have read this code from outer article and i want to modify it as my need. Commented Feb 23, 2015 at 12:57

1 Answer 1

1

The error shows what's wrong - you are trying to load the empty string as the xml document:

oXml.LoadXml(@"");

Obviously the root element is missing here.

Sign up to request clarification or add additional context in comments.

3 Comments

ok. i know i have to set path here. but i studied this code on this article and this not define path of XML. see article second comment.
and it's declared path as @"". Please read full article and it's related comments. this is very useful code for my project. help me out to this problem.
LoadXml() takes string as Xml and not the path. From the Xml point of view the article is wrong if it passes the empty string because it is not a valid Xml. It may have other merits or the empty string is just a shortcut used for brevity - I don't know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.