使用c#邮件消息发送MHT文件
本文关键字:MHT 文件 消息 使用 | 更新日期: 2023-09-27 18:16:23
有没有人得到任何示例代码发送MHT使用SmtpClient和MailMessage在c#中?
我发现了使用替代视图的诱人参考,但我不知道如何使用我的SSRS生成的MHT。
如果任何人有任何工作代码,他们愿意分享,我将非常感激。
所以看起来。net MailMessage不支持开箱即用。我发现了一些方法,它们可以获得不同程度的成功。
MHTML -> HTML解码器
David Benko写了https://github.com/DavidBenko/MHTML-to-HTML-Decoding-in-C-Sharp/blob/master/MHTMLParser.cs,虽然它有效,但当我查看结果电子邮件时,我无法使图像出现。HTML看起来是正确的,只是在Outlook 2010中不工作。
将MimeKit MimeMessage转换为。net邮件消息
杰弗里指出,这是一个开始https://github.com/jstedfast/MimeKit/issues/140。我又遇到了图像没有显示在结果消息中的问题。
使用MimeKit &MailKit
我最终使用https://github.com/jstedfast/MimeKit来完成这项工作。这可以通过以下方式实现:
MimeMessage messageMimeKit = MimeMessage.Load(Request.MapPath("~/Blah/378921.mht"));
messageMimeKit.From.Add(new MailboxAddress("Dev", "developer@gmail.com"));
messageMimeKit.To.Add(new MailboxAddress("Homer", "homer@gmail.com"));
messageMimeKit.Subject = "Another subject line";
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
client.Connect("smtp.gmail.com", 465, true);
client.Authenticate("homer@gmail.com", "*****");
client.Send(messageMimeKit);
client.Disconnect(true);
}
Using System.Net.Http.Formatting
我的方法利用了System.Net.Http.Formatting库中HttpContent上的ReadAsMultipartAsync扩展方法。(microsoft . asp.net . webapi . client nuget包的一部分)
唯一棘手的一点是从文件中获取正确的内容类型。为了使ReadAsMultipartAsync方法工作,它需要将流内容的ContentType头设置为正确的类型("multipart/related"),包括内容类型值的正确边界参数:
multipart/related;
boundary="----=_NextPart_01C35DB7.4B204430"
请注意,由于我的解决方案仅用于发送以MTHML格式导出的SSRS报告中的内容,因此我的代码假设多部分内容只有一个文本/html部分,其余部分为图像,但是该技术是合理的,可以调整为以更通用的方式处理多部分内容。
const string ContentTypePrefix = "Content-Type: ";
AlternateView htmlView = null;
var linkedResources = new List<LinkedResource>();
var content = File.ReadAllText("report.mhtml");
var startIndex = content.IndexOf(ContentTypePrefix, StringComparison.OrdinalIgnoreCase) + ContentTypePrefix.Length;
var endIndex = content.IndexOf("'"", startIndex, StringComparison.Ordinal) + 1;
var contentType = content.Substring(startIndex, endIndex);
using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(content)))
{
using (var stream = new StreamContent(memoryStream))
{
stream.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
if (!stream.IsMimeMultipartContent())
{
throw new Exception("Not correct format.");
}
var parts = stream.ReadAsMultipartAsync().ConfigureAwait(false).GetAwaiter().GetResult();
foreach (var part in parts.Contents)
{
part.Headers.ContentType.CharSet = part.Headers.ContentType.CharSet?.Replace("'"", string.Empty); // Needed since the SSRS report defaults the charset to '"utf-8'", instead of utf-8 and the code fails to find the correct encoder
var compressedContent = part.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
if (!part.Headers.ContentType.MediaType.Contains("image"))
{
var encoding = Encoding.GetEncoding(part.Headers.ContentType.CharSet);
var partContent = encoding.GetString(Convert.FromBase64String(compressedContent));
htmlView = AlternateView.CreateAlternateViewFromString(partContent, encoding, part.Headers.ContentType.MediaType);
}
else
{
linkedResources.Add(new LinkedResource(new MemoryStream(Convert.FromBase64String(compressedContent)), part.Headers.ContentType.MediaType)
{
ContentId = part.Headers.ContentDisposition.FileName.Replace("'"", string.Empty)
});
}
}
}
}
foreach (var linkedResource in linkedResources)
{
htmlView?.LinkedResources.Add(linkedResource);
}
using (var message = new MailMessage("from@mail.com", "to@mail.com", "Subject", string.Empty))
{
message.BodyEncoding = Encoding.UTF8;
message.AlternateViews.Add(htmlView);
using (var client = new SmtpClient("smtpserver.com", 25))
{
client.Send(message);
}
}