2

今天我做了一项服务来接收来自 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!
}
4

1 回答 1

1

为我的问题发现了两个潜在的问题。

第一个来自 SendGrid - 他们发布多部分数据而不为非 unicode 元素指定内容类型。

第二个来自 ServiceStack - 目前它不支持对多部分数据进行 utf-8 以外的编码。

更新:

SendGrid 帮助台承诺会调查这个问题,ServiceStack 现在完全支持多部分数据中的自定义字符集。

至于最初的问题本身,可以访问 ServiceStack 中的缓冲流,如下所述:ServiceStack Runner 可以获取请求正文吗?.

于 2013-09-05T14:21:29.897 回答