Пример #1
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))
            {
                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.SearchAndReplaceVars(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);
        }