C# MailMessage to stream - 编码问题

标签 c# .net amazon-web-services

我正在使用 Amazon SES SendRawEmail API,因此我需要一个 MailMessage 作为内存流。

我在 stackoverflow 上找到了 MailMessage to MemoryStream 问题的几个答案。

解决方案 1: 使用私有(private)方法会导调用子邮件部分编码错误: https://stackoverflow.com/a/8826833

解决方案 2:使用此解决方案时没有编码问题,您发送到拾取目录然后将其读回: https://stackoverflow.com/a/14350088

我非常不喜欢我需要写入临时文件才能使其正常工作这一事实。 有谁知道纯 MemoryStream 解决方案如何弄乱某些编码。

我测试的邮件消息是这样的:

var mailMessage = new MailMessage();
mailMessage.Subject = "HEADER WITH SPECIAL ÆØÅ";
mailMessage.Body = "TEST";

Attachment att = new Attachment(@"C:\AttachmentWithSpecial ÆØÅ.pdf");
mailMessage.Attachments.Add(att);
mailMessage.From = new MailAddress("test@test.com", "NameÆØÅ");
mailMessage.To.Add(new MailAddress("test@test.com", "NameÆØÅ"));

总结:

  • 如果我使用标准 SMTP 发送此邮件,它看起来不错。
  • 如果我使用 SendRawEmail 发送它,如果我使用解决方案 2 生成内存流,它看起来不错
  • 如果我使用 SendRawEmail 发送它,如果我使用解决方案 1 生成内存流,则会出现编码问题。

关于编码问题,我的意思是 'ø' 显示为

enter image description here

最佳答案

不幸的是,MailMessage 对象有问题并且接口(interface)很差。

好消息是 .NET 4.5 在 Send() 中使用 allowUnicode 标志部分修复了它(不幸的是 Send 方法仍然是私有(private)的)

下面修改了“方案一”。 它以与“解决方案 2”相同的方式对主题进行编码。 仅限 .NET Framework 4.5。

private static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message)
{
    Assembly systemAssembly = typeof(SmtpClient).Assembly;
    Type mailWriterType = systemAssembly.GetType("System.Net.Mail.MailWriter");
    const BindingFlags nonPublicInstance = BindingFlags.Instance | BindingFlags.NonPublic;
    ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(nonPublicInstance, null, new[]  typeof(Stream) }, null);

    MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", nonPublicInstance);
    MethodInfo closeMethod = mailWriterType.GetMethod("Close", nonPublicInstance);
    using (MemoryStream memoryStream = new MemoryStream())
    {
        object mailWriter = mailWriterContructor.Invoke(new object[] { memoryStream });
        //AssertHelper.IsTrue(sendMethod.GetParameters().Length > 2, ".NET framework must be 4.5 or higher in order to properly encode email subject.");
        sendMethod.Invoke(message, nonPublicInstance, null,
            new[] { mailWriter, true, false },
            null);
        closeMethod.Invoke(mailWriter, nonPublicInstance, null, new object[] { }, null);
        return memoryStream;
    }
}

关于C# MailMessage to stream - 编码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15831611/

相关文章:

amazon-web-services - 为什么我们需要 AWS 中的私有(private)子网 + NAT 转换?我们不能只使用公共(public)子网 + 正确配置的安全组吗?

c# - 如何序列化包含其他类对象的类(递归序列化?)

.net - Safari 5.1 的必填字段验证器

c# - 将属性添加到列表中的项目

c# - 动画化 TreeView 中项目的添加/删除 - WPF

c# - Entity Framework 数据库表关联

amazon-web-services - 当 jpeg 源是 mjpeg 流时,AWS Rekognition InvalidImageFormatException

amazon-web-services - 无法使用Terraform为ElasticSearch添加2个子网

c# - 以编程方式创建/运行命令文件

c# - 如何在 Node.js 中解压一个 c# 打包的结构