/// <summary> /// Adds external inline attachments (linked resources of the HTML body) of a mail message. /// They are normally generated automatically with all image sources pointing to local files, /// but with this method such files can be added as well. /// </summary> /// <param name="att"></param> public void AddExternalInlineAttachment(FileAttachment att) { _inlineAttExternal.Add(att); }
/// <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 = TextTransferEncoding }; 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); }