Gmail API返回的文本/纯内容编码的差异

问题描述 投票:1回答:1

我正在尝试使用GMail API阅读multipart/mixed电子邮件。目标是将text/plain电子邮件的每个multipart/mixed部分正确解码(可以有许多不同的编码)为C#字符串(即UTF-16):

public static string DecodeTextPart(Google.Apis.Gmail.v1.Data.MessagePart part)
{
    var content_type_header = part.Headers.FirstOrDefault(h => string.Equals(h.Name, "content-type", StringComparison.OrdinalIgnoreCase));

    if (content_type_header == null)
        throw new ArgumentException("No content-type header found in the email part");

    var content_type = new System.Net.Mime.ContentType(content_type_header.Value);

    if (!string.Equals(content_type.MediaType, "text/plain", StringComparison.OrdinalIgnoreCase))
        throw new ArgumentException("The part is not text/plain");

    return Encoding.GetEncoding(content_type.CharSet).GetString(GetAttachmentBytes(part.Body));
}

GetAttachmentBytes返回原始附件字节,不进行转换,而是从GMail使用的base64url encoding进行解码。

[我发现,在很多情况下,这会产生无效的字符串,因为我为附件内容获取的原始字节似乎总是在UTF-8中,即使同一部分的content-type另行声明。

例如给出了电子邮件:

Date: ...
From: ...
Reply-To: ...
Message-ID: ...
To: ...
Subject: Test 1 text file
MIME-Version: 1.0
Content-Type: multipart/mixed;
 boundary="----------0E50FC0802A2FCCAA"

------------0E50FC0802A2FCCAA
Content-Type: text/plain; charset=windows-1251
Content-Transfer-Encoding: 8bit


Content test: Cyrillic, Windows-1251 (à, ÿ, æ)
------------0E50FC0802A2FCCAA
Content-Type: TEXT/PLAIN;
 name="Irrelevant.txt"
Content-transfer-encoding: base64
Content-Disposition: attachment;
 filename="Irrelevant.txt"

VGhpcyBmaWxlIGRvZXMgbm90IGNvbnRhaW4gdXNlZnVsIGluZm9ybWF0aW9u
------------0E50FC0802A2FCCAA--

,我成功地找到了第一部分,上面的代码借助charset=windows-1251表示它是System.Net.Mime.ContentType,然后.GetString()返回了垃圾,因为GetAttachmentBytes返回的实际原始字节对应于UTF-8编码,而不是Windows-1251。

完全相同的发生

Subject: Test 2 text file
MIME-Version: 1.0
Content-Type: multipart/mixed;
 boundary="----------0B716C1D8123D8710"

------------0B716C1D8123D8710
Content-Type: text/plain; charset=koi8-r
Content-Transfer-Encoding: 8bit


Content test: Cyrillic, koi-8 (Б, С, Ц)
------------0B716C1D8123D8710
Content-Type: TEXT/PLAIN;
 name="Irrelevant.txt"
Content-transfer-encoding: base64
Content-Disposition: attachment;
 filename="Irrelevant.txt"

VGhpcyBmaWxlIGRvZXMgbm90IGNvbnRhaW4gdXNlZnVsIGluZm9ybWF0aW9u
------------0B716C1D8123D8710--

[请注意,两封电子邮件中,编码名称后的括号中的三个测试字母相同,Unicode中的外观类似于(а, я, ж),但由于编码方式不同,(正确)在上面引用的电子邮件正文中,这是错误的。] >

如果我“修复”该功能以始终使用Encoding.UTF8而不是GetEncoding(content_type.CharSet),那么它似乎可以在到目前为止完成的测试中起作用。

同时,在两种情况下,GMail界面都正确显示了字母,因此它必须使用正确的声明编码来正确解析传入的电子邮件。

GMail API是否将所有文本块重新编码为UTF-8(包装在base64url中,但报告了原始文本charset?因此,我是否应该始终将UTF-8与GMail API结合使用,而忽略content-typecharset=?还是我的代码有问题?

我正在尝试使用GMail API阅读多部分/混合的电子邮件。目标是正确地将多部分/混合电子邮件的每个文本/纯文本部分(可能有很多,使用不同的编码)解码为...

c# email gmail-api mime content-encoding
1个回答
2
投票
© www.soinside.com 2019 - 2024. All rights reserved.