今天我做了一项服务来接收来自 SendGrid 的电子邮件,最后发送了一封带有文本“终于”的电子邮件,这是在测试期间第一次使用非英语语言。不幸的是,编码已成为我无法解决的问题。
在 ServiceStack 服务中,我有一个字符串属性(在从 SendGrid 发布到服务的输入对象中),其编码不同于 UTF8 或 Unicode(在我的情况下为 KOI8-R)。
public class SengGridEmail : IReturn<SengGridEmailResponse>
{
public string Text { get; set; }
}
当我尝试将此字符串转换为 UTF8 时,我得到 ????s,可能是因为当我访问 Text 属性时,它已经转换为 Unicode(.NET 的内部字符串表示形式)。这个问题和答案说明了这个问题。
我的问题是如何在 ServiceStack 服务或 ASP.NET MVC 控制器中获取原始 KOI8-R 字节,以便我可以将其转换为 UTF8 文本?
更新:
访问base.Request.FormData["text"]
没有帮助
var originalEncoding = Encoding.GetEncoding("KOI8-R");
var originalBytes = originalEncoding.GetBytes(base.Request.FormData["text"]);
但是,如果我从原始发送的邮件中获取 base64 字符串并将其转换为 byte[],然后将这些字节转换为 UTF8 字符串 - 它可以工作。要么base.Request.FormData["text"]
已经是 Unicode .NET 字符串格式,要么(不太可能)它是 SendGrid 方面的东西。
更新 2:这是一个显示正在发生的事情的单元测试:
[Test]
public void EncodingTest()
{
const string originalString = "наконец-то\r\n";
const string base64Koi = "zsHLz87Fwy3Uzw0K";
const string charset = "KOI8-R";
var originalBytes = base64Koi.FromBase64String(); // KOI bytes
var originalEncoding = Encoding.GetEncoding(charset); // KOI Encoding
var originalText = originalEncoding.GetString(originalBytes); // this is initial string correctly converted to .NET representation
Assert.AreEqual(originalString, originalText);
var unicodeEncoding = Encoding.UTF8;
var originalWrongString = unicodeEncoding.GetString(originalBytes); // this is how the KOI string is represented in .NET, equals to base.Request.FormData["text"]
var originalWrongBytes = originalEncoding.GetBytes(originalWrongString);
var unicodeBytes = Encoding.Convert(originalEncoding, unicodeEncoding, originalBytes);
var result = unicodeEncoding.GetString(unicodeBytes);
var unicodeWrongBytes = Encoding.Convert(originalEncoding, unicodeEncoding, originalWrongBytes);
var wrongResult = unicodeEncoding.GetString(unicodeWrongBytes); // this is what I see in DB
Assert.AreEqual(originalString, result);
Assert.AreEqual(originalString, wrongResult); // I want this to pass!
}