/// <summary>
        /// Gets the ready made body part for a mail message either
        /// - as TextPart, if there are no inline attachments
        /// - as MultipartRelated with a TextPart and one or more MimeParts of type inline attachments
        /// </summary>
        public override MimeEntity GetBodyPart()
        {
            ReplaceImgSrcByCid();
            var htmlTextPart = new TextPart("html")
            {
                ContentTransferEncoding = Tools.IsSevenBit(DocHtml)
                                        ? ContentEncoding.SevenBit
                                        : TextTransferEncoding != ContentEncoding.SevenBit
                                                ? TextTransferEncoding
                                                : ContentEncoding.QuotedPrintable,
            };

            htmlTextPart.SetText(CharacterEncoding, DocHtml);              // MimeKit.ContentType.Charset is set using CharacterEncodig
            htmlTextPart.ContentId = MimeUtils.GenerateMessageId();

            if (!InlineAtt.Any())
            {
                return(htmlTextPart);
            }

            /*
             *      multipart/related
             *      text/html
             *      image/jpeg
             *      image/png
             *      image/gif...
             */
            var mpr = new MultipartRelated {
                htmlTextPart
            };


            // Produce attachments as part of the multipart/related MIME part,
            // as described in RFC2387
            // Some older clients may need Inline Attachments instead of LinkedResources:
            // RFC2183: 2.1 The Inline Disposition Type
            // A bodypart should be marked `inline' if it is intended to be displayed automatically upon display of the message. Inline
            // bodyparts should be presented in the order in which they occur, subject to the normal semantics of multipart messages.
            foreach (var ia in InlineAtt)
            {
                try
                {
                    // create an inline image attachment for the file located at path
                    var attachment = new AttachmentBuilder(new FileAttachment(ia.Filename, ia.DisplayName, ia.MimeType), CharacterEncoding,
                                                           TextTransferEncoding, BinaryTransferEncoding).GetAttachment();
                    attachment.ContentDisposition = new MimeKit.ContentDisposition(MimeKit.ContentDisposition.Inline);

                    mpr.Add(attachment);
                }
                catch (FileNotFoundException)
                {
                    BadInlineFiles.Add(ia.Filename);
                }
                catch (IOException)
                {
                    BadInlineFiles.Add(ia.Filename);
                }
            }
            return(mpr);
        }
        public async Task GenerateAndSendInviteMailAsync(Invite invite, string rootUrl, string vorstand)
        {
            MimeMessage message = new MimeMessage();

            message.From.Add(new MailboxAddress("Schulungsportal", emailSender.GetAbsendeAdresse())); //Absender
            message.To.Add(new MailboxAddress(invite.EMailAdress));                                   // Empfaenger
            message.Subject = "Invite Schulungsportal";                                               //Betreff

            InviteMailViewModel imwm = new InviteMailViewModel {
                Vorstand         = vorstand,
                InviteURL        = rootUrl + "/Manage/Register/" + invite.InviteGUID,
                CCLogoFile       = "cclogo.png@" + Guid.NewGuid().ToString(),
                FacebookLogoFile = "fblogo.png@" + Guid.NewGuid().ToString(),
                InstaLogoFile    = "instalogo.png@" + Guid.NewGuid().ToString(),
            };

            var body = new TextPart("html") //Inhalt
            {
                Text = await RunCompileAsync("InviteMail", imwm),
                ContentTransferEncoding = ContentEncoding.Base64,
            };

            var multipart = new MultipartRelated();

            multipart.Add(body);
            // Bilder für Corporate Design
            multipart.Add(LoadInlinePicture("CCLogo.png", imwm.CCLogoFile));
            multipart.Add(LoadInlinePicture("FBLogo.png", imwm.FacebookLogoFile));
            multipart.Add(LoadInlinePicture("InstaLogo.png", imwm.InstaLogoFile));

            message.Body = multipart;

            await emailSender.SendEmailAsync(message);
        }
        private static MimeEntity AppendAlternativeViews(MailMessage mail, MimeEntity originalBody)
        {
            if (mail.AlternateViews.Count == 0)
            {
                return(null);
            }

            var body = new MultipartAlternative();

            if (originalBody != null)
            {
                body.Add(originalBody);
            }

            foreach (var alternativeView in mail.AlternateViews)
            {
                var part = GetMimePart(alternativeView);
                if (alternativeView.BaseUri != null)
                {
                    part.ContentLocation = alternativeView.BaseUri;
                }

                // Determine if the alternative view have linked resources
                if (alternativeView.LinkedResources.Count == 0)
                {
                    body.Add(part);
                    continue;
                }

                // Create a multipart relation
                var type    = part.ContentType.MediaType + "/" + part.ContentType.MediaSubtype;
                var related = new MultipartRelated();

                related.ContentType.Parameters.Add("type", type);
                if (alternativeView.BaseUri != null)
                {
                    related.ContentLocation = alternativeView.BaseUri;
                }

                related.Add(part);

                // Add all the linked resources to the relation
                foreach (var resource in alternativeView.LinkedResources)
                {
                    part = GetMimePart(resource);
                    if (resource.ContentLink != null)
                    {
                        part.ContentLocation = resource.ContentLink;
                    }

                    related.Add(part);
                }

                // Append the linked resource to the alternative view
                body.Add(related);
            }

            return(body);
        }
Пример #4
0
        public void TestDocumentRoot()
        {
            var gif = new MimePart("image", "gif")
            {
                ContentDisposition = new ContentDisposition(ContentDisposition.Inline)
                {
                    FileName = "empty.gif"
                }, ContentId = MimeUtils.GenerateMessageId()
            };
            var jpg = new MimePart("image", "jpg")
            {
                ContentDisposition = new ContentDisposition(ContentDisposition.Inline)
                {
                    FileName = "empty.jpg"
                }, ContentId = MimeUtils.GenerateMessageId()
            };
            var html = new TextPart("html")
            {
                Text = "This is the html body...", ContentId = MimeUtils.GenerateMessageId()
            };
            var    related = new MultipartRelated(gif, jpg, html);
            string start;

            related.ContentType.Parameters["type"]  = "text/html";
            related.ContentType.Parameters["start"] = "<" + html.ContentId + ">";

            Assert.AreEqual(3, related.Count, "Initial Count");
            Assert.AreEqual(html, related.Root, "Initial Root");
            Assert.AreEqual(html, related[2], "Initial Root should be the 3rd item.");

            var root = new TextPart("html")
            {
                Text = "This is the replacement root document..."
            };

            related.Root = root;

            Assert.AreEqual(3, related.Count, "Count");
            Assert.AreEqual(root, related.Root, "Root");
            Assert.AreEqual(root, related[2], "Root should be the 3rd item.");
            Assert.IsNotNull(root.ContentId, "Root's Content-Id should not be null.");
            Assert.IsNotEmpty(root.ContentId, "Root's Content-Id should not be empty.");

            start = "<" + root.ContentId + ">";

            Assert.AreEqual(start, related.ContentType.Parameters["start"], "The start parameter does not match.");

            related.Clear();
            related.Add(gif);
            related.Add(jpg);
            related.Root = html;

            Assert.AreEqual(3, related.Count, "Count");
            Assert.AreEqual(html, related.Root, "Root");
            Assert.AreEqual(html, related[0], "Root should be the 1st item.");

            // Note: MimeKit no longer sets the "start" parameter if the root is the first MIME part due to a bug in Thunderbird.
            Assert.IsNull(related.ContentType.Parameters["start"], "The start parameter should be null.");
        }
Пример #5
0
        void Render(MultipartRelated related)
        {
            var cache = new MultipartRelatedUrlCache(related);

            NSUrlCache.SharedCache = cache;

            Render(related.Root);
        }
Пример #6
0
        protected override void VisitMultipartRelated(MultipartRelated related)
        {
            var root = related.Root;

            _stack.Add(related);
            root.Accept(this);
            _stack.RemoveAt(_stack.Count - 1);
        }
Пример #7
0
        void Render(MultipartRelated related)
        {
            var client = new MultipartRelatedWebViewClient(related);

            webView.SetWebViewClient(client);

            Render(related.Root);
        }
Пример #8
0
        public static void RenderMultipartRelated(MultipartRelated related, WebBrowserEditabil pWebBrowser)
        {
            var root      = related.Root;
            var multipart = root as Multipart;
            var text      = root as TextPart;

            if (multipart != null)
            {
                for (int i = multipart.Count; i > 0; i--)
                {
                    var body = multipart[i - 1] as TextPart;

                    if (body == null)
                    {
                        continue;
                    }

                    if (body.ContentType.IsMimeType("text", "html"))
                    {
                        text = body;
                        break;
                    }

                    if (text == null)
                    {
                        text = body;
                    }
                }
            }
            if (text != null)
            {
                if (text.ContentType.IsMimeType("text", "html"))
                {
                    var ctx       = new MultipartRelatedImageContext(related);
                    var converter = new HtmlToHtml()
                    {
                        HtmlTagCallback = ctx.HtmlTagCallback
                    };
                    var html = converter.Convert(text.Text);

                    pWebBrowser.DocumentText = html;
                }
                else
                {
                    RenderText(text, pWebBrowser);
                }
            }
            else
            {
                return;
            }
        }
Пример #9
0
        protected override void VisitMultipartRelated(MultipartRelated related)
        {
            var root = related.Root;

            // push this multipart/related onto our stack
            stack.Add(related);

            // visit the root document
            root.Accept(this);

            // pop this multipart/related off our stack
            stack.RemoveAt(stack.Count - 1);
        }
Пример #10
0
        void RenderMultipartRelated(MultipartRelated related)
        {
            var root = related.Root;

            if (root == null)
            {
                return;
            }

            var cache = new MultipartRelatedUrlCache(related);

            NSUrlCache.SharedCache = cache;

            Render(root);
        }
Пример #11
0
        void RenderMultipartRelated(MultipartRelated related)
        {
            var root = related.Root;

            if (root == null)
            {
                return;
            }

            var client = new MultipartRelatedWebViewClient(related);

            webView.SetWebViewClient(client);

            Render(root);
        }
        public async Task GenerateAndSendSchulungsNewsletterAsync(List <Schulung> schulungen, string vorstand)
        {
            // Kein newsletter ohne Schulungen
            if (schulungen.Count() == 0)
            {
                return;
            }
            try
            {
                MimeMessage message = new MimeMessage();
                message.From.Add(new MailboxAddress("Schulungsportal", emailSender.GetAbsendeAdresse())); //Absender
                // message.To.Add(new MailboxAddress("@everyone")); // Empfaenger
                message.Subject = "[INFO/noreply] Schulungsnewsletter";                                   //Betreff

                MailViewModel mvm = new MailViewModel
                {
                    CCLogoFile       = "cclogo.png@" + Guid.NewGuid().ToString(),
                    FacebookLogoFile = "fblogo.png@" + Guid.NewGuid().ToString(),
                    InstaLogoFile    = "instalogo.png@" + Guid.NewGuid().ToString(),
                    Schulungen       = schulungen,
                    Vorstand         = vorstand,
                };

                var body = new TextPart("html") //Inhalt
                {
                    Text = await RunCompileAsync("NewsletterMail", mvm),
                    ContentTransferEncoding = ContentEncoding.Base64,
                };

                var multipart = new MultipartRelated();
                multipart.Add(body);
                // Bilder für Corporate Design
                multipart.Add(LoadInlinePicture("CCLogo.png", mvm.CCLogoFile));
                multipart.Add(LoadInlinePicture("FBLogo.png", mvm.FacebookLogoFile));
                multipart.Add(LoadInlinePicture("InstaLogo.png", mvm.InstaLogoFile));

                message.Body = multipart;

                await emailSender.SendEmailAsync(message);
            }
            catch (Exception e)
            {
                logger.Error(e);
                string code = "#601";
                e = new Exception("Fehler beim Versenden des Newsletters (" + e.Message + ") " + code, e);
                throw e;
            }
        }
Пример #13
0
        public string RenderMultipartRelated(MultipartRelated related)
        {
            var root = related.Root;
            var text = root as TextPart;

            if (root is Multipart multipart)
            {
                for (int i = multipart.Count; i > 0; i--)
                {
                    if (!(multipart[i - 1] is TextPart body))
                    {
                        continue;
                    }

                    if (body.ContentType.IsMimeType("text", "html"))
                    {
                        text = body;
                        break;
                    }

                    if (text == null)
                    {
                        text = body;
                    }
                }
            }

            if (text != null)
            {
                if (text.ContentType.IsMimeType("text", "html"))
                {
                    var ctx       = new MultipartRelatedImageContext(related);
                    var converter = new HtmlToHtml()
                    {
                        HtmlTagCallback = ctx.HtmlTagCallback
                    };
                    return(converter.Convert(text.Text));
                }
                else
                {
                    return(RenderText(text));
                }
            }
            else
            {
                return("Uncknown message type.");
            }
        }
Пример #14
0
        public void TestArgumentExceptions()
        {
            var    related = new MultipartRelated();
            string mimeType, charset;

            Assert.Throws <ArgumentNullException> (() => new MultipartRelated((MimeEntityConstructorArgs)null));
            Assert.Throws <ArgumentNullException> (() => related.Open(null, out mimeType, out charset));
            Assert.Throws <ArgumentNullException> (() => related.Open(null));
            Assert.Throws <ArgumentNullException> (() => related.Contains((Uri)null));
            Assert.Throws <ArgumentNullException> (() => related.IndexOf((Uri)null));
            Assert.Throws <ArgumentNullException> (() => related.Accept(null));
            Assert.Throws <ArgumentNullException> (() => related.Root = null);

            Assert.Throws <FileNotFoundException> (() => related.Open(new Uri("http://www.xamarin.com/logo.png"), out mimeType, out charset));
            Assert.Throws <FileNotFoundException> (() => related.Open(new Uri("http://www.xamarin.com/logo.png")));
        }
Пример #15
0
        public void TestGetTextBodyAlternativeInsideRelated()
        {
            var alternative = new MultipartAlternative();
            var plain       = new TextPart("plain")
            {
                Text = "plain\n"
            };
            var flowed = new TextPart(TextFormat.Flowed)
            {
                Text = "flowed\n"
            };
            var richtext = new TextPart("rtf")
            {
                Text = "rtf\n"
            };
            var html = new TextPart("html")
            {
                Text = "html\n"
            };

            alternative.Add(plain);
            alternative.Add(richtext);
            alternative.Add(html);

            var related = new MultipartRelated();

            related.Add(alternative);

            var outer = new MultipartAlternative();

            outer.Add(related);

            Assert.AreEqual("plain\n", outer.TextBody.Replace("\r\n", "\n"), "TextBody");
            Assert.AreEqual("html\n", outer.HtmlBody.Replace("\r\n", "\n"), "HtmlBody");

            alternative.Insert(1, flowed);

            // Note: GetTextBody (Plain) returns Flowed because Flowed is also Plain and is listed after the text/plain part
            Assert.AreEqual("flowed\n", outer.GetTextBody(TextFormat.Plain).Replace("\r\n", "\n"), "Plain");
            Assert.AreEqual("flowed\n", outer.GetTextBody(TextFormat.Flowed).Replace("\r\n", "\n"), "Flowed");
            Assert.AreEqual("rtf\n", outer.GetTextBody(TextFormat.RichText).Replace("\r\n", "\n"), "RichText");
            Assert.AreEqual("html\n", outer.GetTextBody(TextFormat.Html).Replace("\r\n", "\n"), "Html");
            Assert.IsNull(outer.GetTextBody(TextFormat.Enriched), "Enriched");
        }
Пример #16
0
        protected override void VisitMultipartRelated(MultipartRelated related)
        {
            var multipart = new MultipartRelated();
            var root      = related.Root;

            Push(multipart);

            root.Accept(this);

            for (int i = 0; i < related.Count; i++)
            {
                if (related[i] != root)
                {
                    related[i].Accept(this);
                }
            }

            Pop();
        }
        public async Task GenerateAndSendAbsageAnSchulungsdozentMailAsync(Anmeldung anmeldung, String begruendung, String vorstand)
        {
            var         schulung = anmeldung.Schulung;
            MimeMessage message  = new MimeMessage();

            message.From.Add(new MailboxAddress("Schulungsportal", emailSender.GetAbsendeAdresse())); //Absender
            foreach (var dozent in schulung.Dozenten)
            {
                message.To.Add(GetSafeMailboxAddress(dozent.Name, dozent.EMail));                       // Empfaenger
            }
            message.Subject = "Schulung " + anmeldung.Schulung.Titel + ": Abmeldung eines Teilnehmers"; //Betreff

            MailViewModel mwm = new MailViewModel {
                Vorstand         = vorstand,
                Begruendung      = begruendung,
                Anmeldung        = anmeldung,
                Schulung         = schulung,
                CCLogoFile       = "cclogo.png@" + Guid.NewGuid().ToString(),
                FacebookLogoFile = "fblogo.png@" + Guid.NewGuid().ToString(),
                InstaLogoFile    = "instalogo.png@" + Guid.NewGuid().ToString(),
            };

            var body = new TextPart("html") //Inhalt
            {
                Text = await RunCompileAsync("AbsageAnSchulungsdozentMail", mwm),
                ContentTransferEncoding = ContentEncoding.Base64,
            };

            var multipart = new MultipartRelated();

            multipart.Add(body);
            // Bilder für Corporate Design
            multipart.Add(LoadInlinePicture("CCLogo.png", mwm.CCLogoFile));
            multipart.Add(LoadInlinePicture("FBLogo.png", mwm.FacebookLogoFile));
            multipart.Add(LoadInlinePicture("InstaLogo.png", mwm.InstaLogoFile));

            message.Body = multipart;

            await emailSender.SendEmailAsync(message);
        }
        /// <summary>
        /// Diese Methode generiert und schickt eine Mail an die Dozenten der Schulungen einen Tag nach dieser um zu erinnern,
        /// die Anwesenheitsliste an den Schulungsbeauftragten zu senden
        /// </summary>
        /// <param name="anmeldung">Die Anmeldung.</param>
        /// <param name="schulung">Die Schulung, zu die abgesagt wird.</param>
        public async Task GenerateAndSendGeprueftReminderMail(Schulung schulung, string vorstand)
        {
            MimeMessage message = new MimeMessage();

            message.From.Add(new MailboxAddress("Schulungsportal", emailSender.GetAbsendeAdresse())); //Absender
            foreach (var dozent in schulung.Dozenten)
            {
                message.To.Add(GetSafeMailboxAddress(dozent.Name, dozent.EMail));          // Empfaenger
            }
            message.Subject = "[INFO/noreply] Reminder Teilnehmerliste " + schulung.Titel; //Betreff

            var multipart = new MultipartRelated();

            MailViewModel mvm = new MailViewModel
            {
                CCLogoFile       = "cclogo.png@" + Guid.NewGuid().ToString(),
                FacebookLogoFile = "fblogo.png@" + Guid.NewGuid().ToString(),
                InstaLogoFile    = "instalogo.png@" + Guid.NewGuid().ToString(),
                Schulung         = schulung,
                Vorstand         = vorstand,
            };

            var body = new TextPart("html") //Inhalt
            {
                Text = await RunCompileAsync("GeprueftReminder", mvm),
                ContentTransferEncoding = ContentEncoding.Base64,
            };

            multipart.Add(body);
            // Bilder für Corporate Design
            multipart.Add(LoadInlinePicture("CCLogo.png", mvm.CCLogoFile));
            multipart.Add(LoadInlinePicture("FBLogo.png", mvm.FacebookLogoFile));
            multipart.Add(LoadInlinePicture("InstaLogo.png", mvm.InstaLogoFile));
            message.Body = multipart;

            await emailSender.SendEmailAsync(message);
        }
        public static MimeMessage ToMimeMessage(this MailMessage mail)
        {
            if (mail == null)
            {
                throw new ArgumentNullException(nameof(mail));
            }

            var headers = new List <Header>();

            foreach (var field in mail.Headers.AllKeys)
            {
                foreach (var value in mail.Headers.GetValues(field))
                {
                    headers.Add(new Header(field, value));
                }
            }

            var        message = new MimeMessage(headers.ToArray());
            MimeEntity body    = null;

            // Note: If the user has already sent their MailMessage via System.Net.Mail.SmtpClient,
            // then the following MailMessage properties will have been merged into the Headers, so
            // check to make sure our MimeMessage properties are empty before adding them.
            if (mail.Sender != null)
            {
                message.Sender = mail.Sender.ToMailboxAddress();
            }

            if (mail.From != null)
            {
                message.Headers.Replace(HeaderId.From, string.Empty);
                message.From.Add(mail.From.ToMailboxAddress());
            }

            if (mail.ReplyToList.Count > 0)
            {
                message.Headers.Replace(HeaderId.ReplyTo, string.Empty);
                message.ReplyTo.AddRange(mail.ReplyToList.ToInternetAddressList());
            }

            if (mail.To.Count > 0)
            {
                message.Headers.Replace(HeaderId.To, string.Empty);
                message.To.AddRange(mail.To.ToInternetAddressList());
            }

            if (mail.CC.Count > 0)
            {
                message.Headers.Replace(HeaderId.Cc, string.Empty);
                message.Cc.AddRange(mail.CC.ToInternetAddressList());
            }

            if (mail.Bcc.Count > 0)
            {
                message.Headers.Replace(HeaderId.Bcc, string.Empty);
                message.Bcc.AddRange(mail.Bcc.ToInternetAddressList());
            }

            if (mail.SubjectEncoding != null)
            {
                message.Headers.Replace(HeaderId.Subject, mail.SubjectEncoding, mail.Subject ?? string.Empty);
            }
            else
            {
                message.Subject = mail.Subject ?? string.Empty;
            }

            switch (mail.Priority)
            {
            case MailPriority.Normal:
                message.Headers.RemoveAll(HeaderId.XMSMailPriority);
                message.Headers.RemoveAll(HeaderId.Importance);
                message.Headers.RemoveAll(HeaderId.XPriority);
                message.Headers.RemoveAll(HeaderId.Priority);
                break;

            case MailPriority.High:
                message.Headers.Replace(HeaderId.Priority, "urgent");
                message.Headers.Replace(HeaderId.Importance, "high");
                message.Headers.Replace(HeaderId.XPriority, "2 (High)");
                break;

            case MailPriority.Low:
                message.Headers.Replace(HeaderId.Priority, "non-urgent");
                message.Headers.Replace(HeaderId.Importance, "low");
                message.Headers.Replace(HeaderId.XPriority, "4 (Low)");
                break;
            }

            if (!string.IsNullOrEmpty(mail.Body))
            {
                var text = new TextPart(mail.IsBodyHtml ? "html" : "plain");
                text.SetText(mail.BodyEncoding ?? Encoding.UTF8, mail.Body);
                body = text;
            }

            if (mail.AlternateViews.Count > 0)
            {
                var alternative = new MultipartAlternative();

                if (body != null)
                {
                    alternative.Add(body);
                }

                foreach (var view in mail.AlternateViews)
                {
                    var part = GetMimePart(view);

                    if (view.BaseUri != null)
                    {
                        part.ContentLocation = view.BaseUri;
                    }

                    if (view.LinkedResources.Count > 0)
                    {
                        var type    = part.ContentType.MediaType + "/" + part.ContentType.MediaSubtype;
                        var related = new MultipartRelated();

                        related.ContentType.Parameters.Add("type", type);

                        if (view.BaseUri != null)
                        {
                            related.ContentLocation = view.BaseUri;
                        }

                        related.Add(part);

                        foreach (var resource in view.LinkedResources)
                        {
                            part = GetMimePart(resource);

                            if (resource.ContentLink != null)
                            {
                                part.ContentLocation = resource.ContentLink;
                            }

                            related.Add(part);
                        }

                        alternative.Add(related);
                    }
                    else
                    {
                        alternative.Add(part);
                    }
                }

                body = alternative;
            }

            if (body == null)
            {
                body = new TextPart(mail.IsBodyHtml ? "html" : "plain");
            }

            if (mail.Attachments.Count > 0)
            {
                var mixed = new Multipart("mixed");

                if (body != null)
                {
                    mixed.Add(body);
                }

                foreach (var attachment in mail.Attachments)
                {
                    mixed.Add(GetMimePart(attachment));
                }

                body = mixed;
            }

            message.Body = body;

            return(message);
        }
Пример #20
0
        private static MimeEntity ToMimeMessageBody(MailDraftData draft)
        {
            string textBody;

            MailUtil.TryExtractTextFromHtml(draft.HtmlBody, out textBody);

            MultipartAlternative alternative = null;
            MimeEntity           body        = null;

            if (!string.IsNullOrEmpty(textBody))
            {
                var textPart = new TextPart("plain")
                {
                    Text = textBody,
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };

                if (!string.IsNullOrEmpty(draft.HtmlBody))
                {
                    alternative = new MultipartAlternative {
                        textPart
                    };
                    body = alternative;
                }
                else
                {
                    body = textPart;
                }
            }

            if (!string.IsNullOrEmpty(draft.HtmlBody))
            {
                var htmlPart = new TextPart("html")
                {
                    Text = draft.HtmlBody,
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };

                MimeEntity html;

                if (draft.AttachmentsEmbedded.Any())
                {
                    htmlPart.ContentTransferEncoding = ContentEncoding.Base64;

                    var related = new MultipartRelated
                    {
                        Root = htmlPart
                    };

                    related.Root.ContentId = null;

                    foreach (var emb in draft.AttachmentsEmbedded)
                    {
                        var linkedResource = ConvertToMimePart(emb, emb.contentId);
                        related.Add(linkedResource);
                    }

                    html = related;
                }
                else
                {
                    html = htmlPart;
                }

                if (alternative != null)
                {
                    alternative.Add(html);
                }
                else
                {
                    body = html;
                }
            }

            if (!string.IsNullOrEmpty(draft.CalendarIcs))
            {
                var calendarPart = new TextPart("calendar")
                {
                    Text = draft.CalendarIcs,
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };

                calendarPart.ContentType.Parameters.Add("method", draft.CalendarMethod);

                if (alternative != null)
                {
                    alternative.Add(calendarPart);
                }
                else
                {
                    body = calendarPart;
                }
            }


            if (draft.Attachments.Any() || !string.IsNullOrEmpty(draft.CalendarIcs))
            {
                var mixed = new Multipart("mixed");

                if (body != null)
                {
                    mixed.Add(body);
                }

                foreach (var att in draft.Attachments)
                {
                    var attachment = ConvertToMimePart(att);
                    mixed.Add(attachment);
                }

                if (!string.IsNullOrEmpty(draft.CalendarIcs))
                {
                    var filename = "calendar.ics";
                    switch (draft.CalendarMethod)
                    {
                    case Defines.ICAL_REQUEST:
                        filename = "invite.ics";
                        break;

                    case Defines.ICAL_REPLY:
                        filename = "reply.ics";
                        break;

                    case Defines.ICAL_CANCEL:
                        filename = "cancel.ics";
                        break;
                    }

                    var contentType = new ContentType("application", "ics");
                    contentType.Parameters.Add("method", draft.CalendarMethod);
                    contentType.Parameters.Add("name", filename);

                    var calendarResource = new MimePart(contentType)
                    {
                        ContentDisposition      = new ContentDisposition(ContentDisposition.Attachment),
                        ContentTransferEncoding = ContentEncoding.Base64,
                        FileName = filename
                    };

                    var data = Encoding.UTF8.GetBytes(draft.CalendarIcs);

                    var ms = new MemoryStream(data);

                    calendarResource.Content = new MimeContent(ms);

                    mixed.Add(calendarResource);
                }

                body = mixed;
            }

            if (body != null)
            {
                return(body);
            }

            return(new TextPart("plain")
            {
                Text = string.Empty
            });
        }
Пример #21
0
 public MultipartRelatedUrlCache(MultipartRelated related)
 {
     this.related = related;
 }
Пример #22
0
        private MimeMessage BuildMailMessage(NotifyMessage m)
        {
            var mimeMessage = new MimeMessage
            {
                Subject = m.Subject
            };

            var fromAddress = MailboxAddress.Parse(ParserOptions.Default, m.From);

            mimeMessage.From.Add(fromAddress);

            foreach (var to in m.To.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
            {
                mimeMessage.To.Add(MailboxAddress.Parse(ParserOptions.Default, to));
            }

            if (m.ContentType == Pattern.HTMLContentType)
            {
                var textPart = new TextPart("plain")
                {
                    Text = HtmlUtil.GetText(m.Content),
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };

                var multipartAlternative = new MultipartAlternative {
                    textPart
                };

                var htmlPart = new TextPart("html")
                {
                    Text = GetHtmlView(m.Content),
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };

                if (m.EmbeddedAttachments != null && m.EmbeddedAttachments.Length > 0)
                {
                    var multipartRelated = new MultipartRelated
                    {
                        Root = htmlPart
                    };

                    foreach (var attachment in m.EmbeddedAttachments)
                    {
                        var mimeEntity = ConvertAttachmentToMimePart(attachment);
                        if (mimeEntity != null)
                        {
                            multipartRelated.Add(mimeEntity);
                        }
                    }

                    multipartAlternative.Add(multipartRelated);
                }
                else
                {
                    multipartAlternative.Add(htmlPart);
                }

                mimeMessage.Body = multipartAlternative;
            }
            else
            {
                mimeMessage.Body = new TextPart("plain")
                {
                    Text = m.Content,
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };
            }

            if (!string.IsNullOrEmpty(m.ReplyTo))
            {
                mimeMessage.ReplyTo.Add(MailboxAddress.Parse(ParserOptions.Default, m.ReplyTo));
            }

            mimeMessage.Headers.Add("Auto-Submitted", string.IsNullOrEmpty(m.AutoSubmitted) ? "auto-generated" : m.AutoSubmitted);

            return(mimeMessage);
        }
Пример #23
0
        /// <summary>
        /// Gets the ready made body part for a mail message either
        /// - as TextPart, if there are no inline attachments
        /// - as MultipartRelated with a TextPart and one or more MimeParts of type inline attachments
        /// </summary>
        public override MimeEntity GetBodyPart()
        {
            // remove all Script elements, because they cannot be used in mail messages
            foreach (var element in _htmlDocument.All.Where(e => e is IHtmlScriptElement).ToList())
            {
                element.Remove();
            }

            // set the HTML title tag from email subject
            var titleEle = _htmlDocument.All.FirstOrDefault(m => m is IHtmlTitleElement) as IHtmlTitleElement;

            if (titleEle != null)
            {
                titleEle.Text = _mailMergeMessage.SearchAndReplaceVars(_mailMergeMessage.Subject, _dataItem);
            }

            // read the <base href="..."> tag in order to find the embedded image files later on
            var baseEle = _htmlDocument.All.FirstOrDefault(m => m is IHtmlBaseElement) as IHtmlBaseElement;
            var baseDir = baseEle?.Href == null ? null : new Uri(baseEle.Href);

            // only replace the base url if it was not set programmatically
            if (_docBaseUri == null)
            {
                _docBaseUri = baseDir;
            }

            // remove if base tag is local file reference, because it's not usable in the resulting HTML
            if (baseEle != null && baseDir != null && baseDir.Scheme == UriScheme.File)
            {
                baseEle.Remove();
            }

            ReplaceImgSrcByCid();

            // replace placeholders only in the HTML Body, because e.g.
            // in the header there may be CSS definitions with curly brace which collide with SmartFormat {placeholders}
            _htmlDocument.Body.InnerHtml = _mailMergeMessage.SearchAndReplaceVars(_htmlDocument.Body.InnerHtml, _dataItem);

            var htmlTextPart = new TextPart("html")
            {
                ContentTransferEncoding = Tools.IsSevenBit(DocHtml)
                    ? ContentEncoding.SevenBit
                    : TextTransferEncoding != ContentEncoding.SevenBit
                        ? TextTransferEncoding
                        : ContentEncoding.QuotedPrintable,
            };

            htmlTextPart.SetText(CharacterEncoding, DocHtml);  // MimeKit.ContentType.Charset is set using CharacterEncoding
            htmlTextPart.ContentId = MimeUtils.GenerateMessageId();

            if (!InlineAtt.Any())
            {
                return(htmlTextPart);
            }

            /*
             *  multipart/related
             *  text/html
             *  image/jpeg
             *  image/png
             *  image/gif...
             */
            var mpr = new MultipartRelated {
                htmlTextPart
            };

            // Produce attachments as part of the multipart/related MIME part,
            // as described in RFC2387
            // Some older clients may need Inline Attachments instead of LinkedResources:
            // RFC2183: 2.1 The Inline Disposition Type
            // A bodypart should be marked `inline' if it is intended to be displayed automatically upon display of the message. Inline
            // bodyparts should be presented in the order in which they occur, subject to the normal semantics of multipart messages.
            foreach (var ia in InlineAtt)
            {
                try
                {
                    var readyInlineAtt = new FileAttachment(_mailMergeMessage.SearchAndReplaceVarsInFilename(ia.Filename, _dataItem), _mailMergeMessage.SearchAndReplaceVars(ia.DisplayName, _dataItem));
                    // create an inline image attachment for the file located at path
                    var attachment = new AttachmentBuilder(readyInlineAtt, CharacterEncoding,
                                                           TextTransferEncoding, BinaryTransferEncoding).GetAttachment();
                    attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Inline);
                    attachment.ContentId          = ia.DisplayName;
                    attachment.FileName           = null; // not needed for inline attachments, save some space

                    mpr.Add(attachment);
                }
                catch (FileNotFoundException)
                {
                    BadInlineFiles.Add(ia.Filename);
                }
                catch (IOException)
                {
                    BadInlineFiles.Add(ia.Filename);
                }
            }
            return(mpr);
        }
 public MultipartRelatedWebViewClient(MultipartRelated related)
 {
     this.related = related;
 }
Пример #25
0
 public MultipartRelatedImageContext(MultipartRelated related)
 {
     this.related = related;
 }
Пример #26
0
 protected internal override void VisitMultipartRelated(MultipartRelated related)
 {
     MultipartRelated++;
     base.VisitMultipartRelated(related);
 }
Пример #27
0
        void RenderMultipartRelated(MultipartRelated related)
        {
            var root      = related.Root;
            var multipart = root as Multipart;
            var text      = root as TextPart;

            if (multipart != null)
            {
                // Note: the root document can sometimes be a multipart/alternative.
                // A multipart/alternative is just a collection of alternate views.
                // The last part is the format that most closely matches what the
                // user saw in his or her email client's WYSIWYG editor.
                for (int i = multipart.Count; i > 0; i--)
                {
                    var body = multipart[i - 1] as TextPart;

                    if (body == null)
                    {
                        continue;
                    }

                    // our preferred mime-type is text/html
                    if (body.ContentType.Matches("text", "html"))
                    {
                        text = body;
                        break;
                    }

                    if (text == null)
                    {
                        text = body;
                    }
                }
            }

            // check if we have a text/html document
            if (text != null && text.ContentType.Matches("text", "html"))
            {
                var      doc   = new HtmlAgilityPack.HtmlDocument();
                var      saved = new Dictionary <MimePart, string> ();
                TextPart html;

                doc.LoadHtml(text.Text);

                // find references to related MIME parts and replace them with links to links to the saved attachments
                foreach (var img in doc.DocumentNode.SelectNodes("//img[@src]"))
                {
                    var src = img.Attributes["src"];
                    int index;
                    Uri uri;

                    if (src == null || src.Value == null)
                    {
                        continue;
                    }

                    // parse the <img src=...> attribute value into a Uri
                    if (Uri.IsWellFormedUriString(src.Value, UriKind.Absolute))
                    {
                        uri = new Uri(src.Value, UriKind.Absolute);
                    }
                    else
                    {
                        uri = new Uri(src.Value, UriKind.Relative);
                    }

                    // locate the index of the attachment within the multipart/related (if it exists)
                    if ((index = related.IndexOf(uri)) != -1)
                    {
                        var attachment = related[index] as MimePart;

                        // make sure the referenced part is a MimePart (as opposed to another Multipart or MessagePart)
                        if (attachment != null)
                        {
                            string fileName;

                            // save the attachment (if we haven't already saved it)
                            if (!saved.TryGetValue(attachment, out fileName))
                            {
                                fileName = attachment.FileName;

                                if (string.IsNullOrEmpty(fileName))
                                {
                                    fileName = Guid.NewGuid().ToString();
                                }

                                using (var stream = File.Create(fileName))
                                    attachment.ContentObject.DecodeTo(stream);

                                saved.Add(attachment, fileName);
                            }

                            // replace the <img src=...> value with the local file name
                            src.Value = "file://" + Path.GetFullPath(fileName);
                        }
                    }
                }

                if (saved.Count > 0)
                {
                    // we had to make some modifications to the original html part, so create a new
                    // (temporary) text/html part to render
                    html = new TextPart("html");
                    using (var writer = new StringWriter()) {
                        doc.Save(writer);

                        html.Text = writer.GetStringBuilder().ToString();
                    }
                }
                else
                {
                    html = text;
                }

                RenderTextPart(html);
            }
            else
            {
                // we don't know what we have, so render it as an entity
                RenderEntity(related.Root);
            }
        }
Пример #28
0
        void RenderMultipartRelated(MultipartRelated related)
        {
            var root      = related.Root;
            var multipart = root as Multipart;
            var text      = root as TextPart;

            if (multipart != null)
            {
                // Note: the root document can sometimes be a multipart/alternative.
                // A multipart/alternative is just a collection of alternate views.
                // The last part is the format that most closely matches what the
                // user saw in his or her email client's WYSIWYG editor.
                for (int i = multipart.Count; i > 0; i--)
                {
                    var body = multipart[i - 1] as TextPart;

                    if (body == null)
                    {
                        continue;
                    }

                    // our preferred mime-type is text/html
                    if (body.ContentType.IsMimeType("text", "html"))
                    {
                        text = body;
                        break;
                    }

                    if (text == null)
                    {
                        text = body;
                    }
                }
            }

            // check if we have a text/html document
            if (text != null)
            {
                if (text.ContentType.IsMimeType("text", "html"))
                {
                    // replace image src urls that refer to related MIME parts with "data:" urls
                    // Note: we could also save the related MIME part content to disk and use
                    // file:// urls instead.
                    var ctx       = new MultipartRelatedImageContext(related);
                    var converter = new HtmlToHtml()
                    {
                        HtmlTagCallback = ctx.HtmlTagCallback
                    };
                    var html = converter.Convert(text.Text);

                    webBrowser.DocumentText = html;
                }
                else
                {
                    RenderText(text);
                }
            }
            else
            {
                // we don't know how to render this type of content
                return;
            }
        }
Пример #29
0
        private static MimeEntity ToMimeMessageBody(MailDraft draft)
        {
            var linkedResources = new AttachmentCollection(true);
            var attachments     = new AttachmentCollection();

            string textBody;

            MailUtil.TryExtractTextFromHtml(draft.HtmlBody, out textBody);

            MultipartAlternative multipartAlternative = null;
            MimeEntity           body = null;

            if (!string.IsNullOrEmpty(textBody))
            {
                var textPart = new TextPart("plain")
                {
                    Text = textBody,
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };

                if (!string.IsNullOrEmpty(draft.HtmlBody))
                {
                    multipartAlternative = new MultipartAlternative {
                        textPart
                    };
                    body = multipartAlternative;
                }
                else
                {
                    body = textPart;
                }
            }

            if (!string.IsNullOrEmpty(draft.HtmlBody))
            {
                var htmlPart = new TextPart("html")
                {
                    Text = draft.HtmlBody,
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };

                MimeEntity tempPart;

                if (draft.AttachmentsEmbedded.Any())
                {
                    var multipartRelated = new MultipartRelated
                    {
                        Root = htmlPart
                    };

                    foreach (var emb in draft.AttachmentsEmbedded)
                    {
                        MimeEntity linkedResource;

                        if (!emb.data.Any())
                        {
                            var s3Key = MailStoragePathCombiner.GerStoredFilePath(emb);

                            var contentType =
                                ContentType.Parse(string.IsNullOrEmpty(emb.contentType)
                                    ? MimeMapping.GetMimeMapping(emb.fileName)
                                    : emb.contentType);

                            using (var stream = StorageManager
                                                .GetDataStoreForAttachments(emb.tenant)
                                                .GetReadStream(s3Key))
                            {
                                linkedResource = linkedResources.Add(emb.fileName, stream, contentType);
                            }
                        }
                        else
                        {
                            linkedResource = linkedResources.Add(emb.fileName, emb.data);
                        }

                        linkedResource.ContentId = emb.contentId;

                        multipartRelated.Add(linkedResource);
                    }

                    tempPart = multipartRelated;
                }
                else
                {
                    tempPart = htmlPart;
                }

                if (multipartAlternative != null)
                {
                    multipartAlternative.Add(tempPart);
                }
                else
                {
                    body = tempPart;
                }
            }

            if (!string.IsNullOrEmpty(draft.CalendarIcs))
            {
                var calendarPart = new TextPart("calendar")
                {
                    Text = draft.CalendarIcs,
                    ContentTransferEncoding = ContentEncoding.QuotedPrintable
                };

                calendarPart.ContentType.Parameters.Add("method", draft.CalendarMethod);

                if (multipartAlternative != null)
                {
                    multipartAlternative.Add(calendarPart);
                }
                else
                {
                    body = calendarPart;
                }
            }


            if (draft.Attachments.Any() || !string.IsNullOrEmpty(draft.CalendarIcs))
            {
                var multipart = new Multipart("mixed");

                if (body != null)
                {
                    multipart.Add(body);
                }

                foreach (var att in draft.Attachments)
                {
                    MimeEntity attachmentResource;

                    if (!att.data.Any())
                    {
                        var s3Key = MailStoragePathCombiner.GerStoredFilePath(att);

                        using (var stream = StorageManager
                                            .GetDataStoreForAttachments(att.tenant)
                                            .GetReadStream(s3Key))
                        {
                            attachmentResource = attachments.Add(att.fileName, stream);
                        }
                    }
                    else
                    {
                        attachmentResource = attachments.Add(att.fileName, att.data);
                    }

                    multipart.Add(attachmentResource);
                }

                if (!string.IsNullOrEmpty(draft.CalendarIcs))
                {
                    var filename = "calendar.ics";
                    switch (draft.CalendarMethod)
                    {
                    case "REQUEST":
                        filename = "invite.ics";
                        break;

                    case "REPLY":
                        filename = "reply.ics";
                        break;

                    case "CANCEL":
                        filename = "cancel.ics";
                        break;
                    }

                    var contentType = new ContentType("application", "ics");
                    contentType.Parameters.Add("method", draft.CalendarMethod);
                    contentType.Parameters.Add("name", filename);

                    var data = Encoding.UTF8.GetBytes(draft.CalendarIcs);

                    var calendarResource = attachments.Add(filename, data, contentType);
                    multipart.Add(calendarResource);
                }

                body = multipart;
            }

            if (body != null)
            {
                return(body);
            }

            return(new TextPart("plain")
            {
                Text = string.Empty
            });
        }