MimeKit字符编码/解码问题

时间:2017-03-27 17:34:19

标签: c# email character-encoding mimekit

使用MimeKit.eml文件转换为.msg文件时,我遇到了一个似乎与编码有关的问题。

使用包含以下内容的EML文件,例如:

--__NEXTPART_20160610_5EF5CF91_471687D
Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit

添付ファイル名テスト

结果是身体内容中的垃圾:

・Y・t・t・@・C・・・シ・e・X・g

此外,当读取EML文件时,base-64编码的ü字符显示为??。我已经下载了最新版本的MimeKit,但它似乎没什么区别。

使用Outlook 2016正确打开.eml文件,但使用MimeKit似乎无法正确读取和解码文件。

1 个答案:

答案 0 :(得分:1)

上述MIME代码段存在一些问题:(

Content-Transfer-Encoding: 7bit显然不是真的,但不太可能是问题(由于这个原因,MimeKit会忽略7bit8bit的值。)

但最重要的是,charset参数为iso-2022-jp,但内容本身非iso-2022-jp(看起来像utf-8)。

当您获得TextPart.Text值时,MimeKit通过使用Content-Type标头中指定的字符集转换原始流内容来获取该字符串。如果这是错误的,那么Text属性也将具有错误的值。

好消息是TextPartGetText方法允许您指定字符集覆盖。

我建议尝试:

var text = part.GetText (Encoding.UTF8);

看看是否有效。

FWIW,iso-2022-jp是一种强制日文字符变成7bit ascii形式的编码,看起来像完全乱码。如果日文文本实际位于iso-2022-jp中,那么这就是您的日文文字:

BE:IU%U%!%$%kL>%F%9%H

我知道的不是iso-2022-jp:)

<强>更新

最终,解决方案可能会是这样的:

var encodings = new List<Encoding> ();
string text = null;

try {
    var encoding = Encoding.GetEncoding (part.ContentType.Charset,
        new EncoderExceptionFallback (),
        new DecoderExceptionFallback ());
    encodings.Add (encoding);
} catch (ArgumentException) {
} catch (NotSupportedException) {
}

// add utf-8 as our first fallback
encodings.Add (Encoding.GetEncoding (65001, 
    new EncoderExceptionFallback (),
    new DecoderExceptionFallback ()));

// add iso-8859-1 as our final fallback
encodings.Add (Encoding.GetEncoding (28591, 
    new EncoderExceptionFallback (),
    new DecoderExceptionFallback ()));

for (int i = 0; i < encodings.Count; i++) {
    try {
        text = part.GetText (encodings[i]);
        break;
    } catch (DecoderFallbackException) {
        // this means that the content did not convert cleanly
    }
}