【问题标题】:How to read string from HttpRequest form data in correct encoding如何以正确的编码从 HttpRequest 表单数据中读取字符串
【发布时间】:2013-09-04 13:41:35
【问题描述】:

今天我做了一项服务来接收来自 SendGrid 的电子邮件,最后我发送了一封带有“终于”文本的电子邮件,这是在测试期间第一次使用非英语语言。不幸的是,编码已成为我无法解决的问题。

在 ServiceStack 服务中,我有一个字符串属性(在从 SendGrid 发布到服务的输入对象中),其编码不同于 UTF8 或 Unicode(在我的情况下为 KOI8-R)。

public class SengGridEmail : IReturn<SengGridEmailResponse>
    {
        public string Text { get; set; }
    }

当我尝试将此字符串转换为 UTF8 时,我得到 ????s,可能是因为当我访问 Text 属性时,它已经转换为 Unicode(.NET 的内部字符串表示形式)。 This question and answer 说明问题。

我的问题是如何在 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!
}

【问题讨论】:

  • 我发现 SendGrid 为非 unicode elmenets 发送没有 Content-Type 标头的多部分数据,即使他们这样做了 ServiceStack 也不会解析它(有一行 //TODO :在 HttpListenerRequestWrapper.cs 中添加更多编码支持)。我相信第一部分是一个 SendGrid 错误,第二部分我正在准备修复

标签: c# asp.net encoding servicestack sendgrid


【解决方案1】:

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

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

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

更新:

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

至于最初的问题本身,可以访问 ServiceStack 中的缓冲流,如下所述:Can ServiceStack Runner Get Request Body?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-04
    • 1970-01-01
    • 2017-11-26
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    相关资源
    最近更新 更多