電子メールメッセージの本文(HTML)に埋め込まれた複数の画像(グラフ)を使用してユーザーに電子メールを送信するプログラムを書いています。
ここにあるサンプルを試したところ、1つの画像のみを埋め込む必要があるときにうまくいきました http://www.systemnetmail.com/faq/4.4.aspx 。
しかし、以下のコードを使用して複数の画像を埋め込もうとすると、画像は埋め込まれず、添付ファイルとして送信されます。
public MailMessage MailMessage(Metric metric, DateTime date)
{
MailMessage msg = new MailMessage();
msg.From = new MailAddress("[email protected]", "User1");
msg.To.Add(new MailAddress("[email protected]"));
msg.Subject = "Trend for metric: " + metric.Name;
msg.IsBodyHtml = true;
// Generate the charts for the given metric
var charts = this.GenerateCharts(metric, date);
int i = 0;
string htmlBody = "<html><body>";
List<LinkedResource> resources = new List<LinkedResource>();
foreach (var chart in charts)
{
string imageTag = string.Format("<img src=cid:chart{0} /><br>", i);
htmlBody += imageTag;
LinkedResource graph = new LinkedResource(chart.Value, "image/jpeg");
graph.ContentId = "chart" + i;
resources.Add(graph);
i++;
}
htmlBody += "</body></html>";
// Alternate view for embedded images
AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, MediaTypeNames.Text.Html);
AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
// Add all the images as linked resources
resources.ForEach(x => avImages.LinkedResources.Add(x));
// Add the views for image
msg.AlternateViews.Add(avText);
msg.AlternateViews.Add(avImages);
return msg;
}
私が欠けているものとしての手がかりはありますか?メールの添付ファイルとしても送信される.htmファイルを確認したところ、htmlソースは次のようになります。
<html>><body><img src=cid:chart0 /><br><img src=cid:chart1 /><br><img src=cid:chart2/><br><img src=cid:chart3 /><br><img src=cid:chart4 /><br></body></html>
したがって、Qは、添付ファイルとしてではなく、html本文で複数の画像を送信する方法です。
だから、私は実際の問題が何であるかを理解したと思います
// Alternate view for embedded images
AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, MediaTypeNames.Text.Html);
AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
ご覧のとおり、両方のビューはText.Htmlとして指定されているため、最初のビューが次のビューをオーバーライドしているため、テキストと画像のみが添付ファイルとして送信されているのがわかります
次の変更を加えましたが、期待どおりに機能しました
AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, **MediaTypeNames.Text.Plain**);
AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
System.Net.Mail
の使用時に画像を電子メールに埋め込むもう1つの方法は、
ローカルドライブの画像をメールに添付してcontentID
を割り当て、後でこのcontentID
を画像URLで使用します。
これは次の方法で実行できます。
var contentID = "Image";
var inlineLogo = new Attachment(@"C:\Desktop\Image.jpg");
inlineLogo.ContentId = contentID;
inlineLogo.ContentDisposition.Inline = true;
inlineLogo.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
msg.IsBodyHtml = true;
msg.Attachments.Add(inlineLogo);
msg.Body = "<htm><body> <img src=\"cid:" + contentID + "\"> </body></html>";
最初に、埋め込まれた画像に絶対URIを使用しようとすることができます。これが RFC-2557 の例です。
From: [email protected]
To: [email protected]
Subject: A simple example
Mime-Version: 1.0
Content-Type: multipart/related; boundary="boundary-example";
type="text/html"; start="<foo3@[email protected]>"
--boundary-example
Content-Type: text/html;charset="US-ASCII"
Content-ID: <foo3@[email protected]>
... text of the HTML document, which might contain a URI
referencing a resource in another body part, for example
through a statement such as:
<IMG SRC="http://www.ietf.cnri.reston.va.us/images/ietflogo.gif" ALT="IETF logo">
--boundary-example
Content-Location:
http://www.ietf.cnri.reston.va.us/images/ietflogo.gif
Content-Type: IMAGE/GIF
Content-Transfer-Encoding: BASE64
R0lGODlhGAGgAPEAAP/////ZRaCgoAAAACH+PUNvcHlyaWdodCAoQykgMTk5
NSBJRVRGLiBVbmF1dGhvcml6ZWQgZHVwbGljYXRpb24gcHJvaGliaXRlZC4A
etc...
--boundary-example--
ContentIdの代わりに LinkedResource.ContentLink property を割り当てるだけです。
2番目、 「データ」URLスキーム を使用して画像をHTMLに直接埋め込むことができます。
<IMG
SRC="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw
AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH
hhx4dbgYKAAA7"
ALT="Larry">
ところで、あなたのhtmlマークアップは整形式ではありません。 “ foreach” vs“ ForEach” にも興味があるかもしれません
オンラインの画像がある場合、つまりホストされているサイトから送信する場合は、srcにURLを置くだけでそれらの画像を参照することをお勧めします。
<!-- using artplastika examples -->
<IMG SRC="http://www.ietf.cnri.reston.va.us/images/ietflogo.gif" ALT="IETF logo" />
ほとんどのニュースレターはこの方法を使用しており、自分自身を埋め込むよりも軽量で、リソースの消費が少ないと思います。
お役に立てれば
私の代替:
まず、少しの拡張:
public static class RegexExtensions
{
public static string GetPattern(this IEnumerable<string> valuesToSearch)
{
return string.Format("({0})", string.Join("|", valuesToSearch));
}
}
次に、フォルダから画像名を取得します。
private string[] GetFullNamesOfImages()
{
string images = Path.Combine(_directoryName, "Images");
if (!Directory.Exists(images))
return new string[0];
return Directory.GetFiles(images);
}
次に、イメージ名をcidで置き換えます。
private string InsertImages(string body)
{
var images = GetFullNamesOfImages().Select(Path.GetFileName).ToArray();
return Regex.Replace(body, "(Images/)?" + images.GetPattern(), "cid:$2", RegexOptions.IgnoreCase | RegexOptions.Compiled);
}
ここでbody-はHTML本文であり、たとえば、<img src="Images/logo_shadow.png" alt="" style="width: 100%;" />
は<img src="cid:logo_shadow.png" alt="" style="width: 100%;" />
に置き換えられます
次に、最後のアクション:画像自体をメールに追加します。
private MailMessage CreateMail(SmtpClient smtp, string toAddress, string body)
{
var images = GetFullNamesOfImages();
string decodedBody = WebUtility.HtmlDecode(body);
var text = AlternateView.CreateAlternateViewFromString(decodedBody, null, MediaTypeNames.Text.Plain);
var html = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html);
foreach (var image in images)
{
html.LinkedResources.Add(new LinkedResource(image, new ContentType("image/png"))
{
ContentId = Path.GetFileName(image)
});
}
var credentials = (NetworkCredential) smtp.Credentials;
var message = new MailMessage(new MailAddress(credentials.UserName), new MailAddress(toAddress))
{
Subject = "Some subj",
Body = decodedBody
};
message.AlternateViews.Add(text);
message.AlternateViews.Add(html);
return message;
}
AlternateView avHtml = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html);
LinkedResource inline = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath("~/Images/e1.jpg"), MediaTypeNames.Image.Jpeg);
inline.ContentId = "1";
inline.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
avHtml.LinkedResources.Add(inline);
LinkedResource inline1 = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath("~/CImages/2.jpg"), MediaTypeNames.Image.Jpeg);
inline1.ContentId = "2";
inline1.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
avHtml.LinkedResources.Add(inline1);
LinkedResource inline2 = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath("~/Images/3.jpg"), MediaTypeNames.Image.Jpeg);
inline2.ContentId = "3";
inline2.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
avHtml.LinkedResources.Add(inline2);
LinkedResource inline3 = new LinkedResource(System.Web.HttpContext.Current.Server.MapPath("~/Content/Images/4.jpg"), MediaTypeNames.Image.Jpeg);
inline3.ContentId = "4";
inline3.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
avHtml.LinkedResources.Add(inline3);
MailMessage mail = new MailMessage();
mail.AlternateViews.Add(avHtml);
HTML:
<img src="cid:1" alt="" />
<img src="cid:2" alt="" />
<img src="cid:3" alt="" /`
<img src="cid:4" alt="" />
以下を試してください:
private static ICollection<LinkedResource> GetLinkedResources()
{
var linkedResources = new List<LinkedResource>();
linkedResources.Add(new LinkedResource(@"imagepath")
{
ContentId = "HeaderId",
TransferEncoding = TransferEncoding.Base64
});
linkedResources.Add(new LinkedResource(@"imagepath")
{
ContentId = "MapId",
TransferEncoding = TransferEncoding.Base64
});
return linkedResources;
}
その後、次のようにメソッドを呼び出すことができます。
mailMessage.AlternateViews.Add(GetEmbeddedImage(body));