使用C#Mail Message发送MHT文件

时间:2015-10-06 05:40:36

标签: c#

有没有人在C#中使用SmtpClient和MailMessage发送MHT示例代码?

我发现了使用Alternate Views的引人入胜的参考资料,但我无法弄清楚如何使用我的SSRS生成的MHT来完成这项工作。

如果有人有任何他们愿意分享的工作代码,我将非常感激。

2 个答案:

答案 0 :(得分:2)

因此看起来.NET MailMessage不支持开箱即用。我发现了一些可以用不同程度的方法。

MHTML - > HTML解码器

大卫·本科写了https://github.com/DavidBenko/MHTML-to-HTML-Decoding-in-C-Sharp/blob/master/MHTMLParser.cs虽然它有效,但是当我查看生成的电子邮件时,我无法显示图像。 HTML看起来很正确,它在Outlook 2010中无效。

将MimeKit MimeMessage转换为.NET Mail消息

正如杰弗里所指出的那样,这是一个开始https://github.com/jstedfast/MimeKit/issues/140。我再次遇到问题,图片没有显示在结果消息中。

使用MimeKit& MailKit

我最终使用https://github.com/jstedfast/MimeKit来完成这项工作。这可以通过以下方式实现:

[self addChildViewController:myViewController];
[self.view addSubview:myViewController.view];
[myViewControllerController didMoveToParentViewController:self];

答案 1 :(得分:1)

使用System.Net.Http.Formatting

我的方法利用System.Net.Http.Formatting库中的HttpContent的ReadAsMultipartAsync扩展方法。 (Microsoft.AspNet.WebApi.Client nuget包的一部分)

唯一棘手的问题是从文件中获取正确的内容类型。为了使ReadAsMultipartAsync方法起作用,它需要将流内容上的ContentType标头设置为正确的类型(“ multipart / related”),包括内容类型值上的正确的边界参数:

multipart/related;
    boundary="----=_NextPart_01C35DB7.4B204430"

请注意,由于我的解决方案仅用于发送以MTHML格式导出的SSRS报告中的内容,因此我的代码假定多部分内容只有一个text / 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);
    }
}