简体   繁体   English

C#MailMessage流-编码问题

[英]C# MailMessage to stream - encoding issue

Iam using Amazon SES SendRawEmail API hence i need a MailMessage as a Memorystream. 我使用Amazon SES SendRawEmail API,因此我需要MailMessage作为Memorystream。

I have found several answers to the MailMessage to MemoryStream issue here on stackoverflow. 我在这里在stackoverflow上找到了MailMessage to MemoryStream问题的几个答案。

Solution 1: Using the one that uses private methods it results in wrong encoding of parts of the email: https://stackoverflow.com/a/8826833 解决方案1:使用一种使用私有方法的方法会导致部分电子邮件的错误编码: https : //stackoverflow.com/a/8826833

Solution 2: No Encoding problems using this solution where you send to a pickup directory and then read it back in: https://stackoverflow.com/a/14350088 解决方案2:使用此解决方案时,没有编码问题,您可以将其发送到提取目录,然后在以下位置重新读取它: https : //stackoverflow.com/a/14350088

I very much dislike the fact that i need to write to a temporary file to make this work correctly. 我非常不喜欢需要写入临时文件以使其正常工作的事实。 Does anyone have any idea how the pure MemoryStream solution can mess up some of the encoding. 有谁知道纯MemoryStream解决方案如何弄乱某些编码。

The mail message iam testing with is this: 用iam测试的邮件消息是这样的:

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ÆØÅ"));

To summarize: 总结一下:

  • If i send this message with standard SMTP it looks good. 如果我使用标准SMTP发送此消息,它看起来不错。
  • If i send it using SendRawEmail it looks good if i generated the memorystream by using solution 2 如果我使用SendRawEmail发送它,如果我使用解决方案2生成了内存流,则看起来不错
  • If i send it using SendRawEmail it has encoding issues if i generated the memorystream by using solution 1. 如果我使用SendRawEmail发送它,如果我使用解决方案1生成了内存流,则它存在编码问题。

With encoding issues i mean 'ø' showing up as 对于编码问题,我的意思是“ø”显示为

在此处输入图片说明

Did you try to explicitly specify encoding for Subject / Body and MailAddress? 您是否尝试为主题/正文和MailAddress明确指定编码?

I guess that when .NET writes mails to folder it can somehow to define the right encoding (or maybe File Reader somehow can find the right encoding to convert data). 我猜想当.NET将邮件写入文件夹时,它可以以某种方式定义正确的编码(或者File Reader可以以某种方式找到正确的编码来转换数据)。 And in memory everything is in default encoding, which does not work for you. 并且在内存中,所有内容均采用默认编码,这对您不起作用。

Unfortunately MailMessage object is buggy and has poor interface. 不幸的是,MailMessage对象是错误的,并且界面较差。

The good thing is that .NET 4.5 partially fixed it with allowUnicode flag in Send() (unfortunately Send method is still private) 好的是,.NET 4.5使用Send()中的allowUnicode标志部分修复了它(不幸的是,Send方法仍然是私有的)

Below is modified "Solution 1". 下面是修改的“解决方案1”。 It encodes subject the same way as "Solution 2". 它对主题的编码方式与“解决方案2”相同。 .NET Framework 4.5 only. 仅限.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;
    }
}
message.BodyEncoding = message.SubjectEncoding = message.HeadersEncoding = Encoding.UTF8;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM