C#,UTF-8和编码字符 (注意:这是一个提问标题,无需回答)

5
这可能有点靠猜测,如果我的问题听起来像个疯子的胡言乱语,我在此提前道歉。
作为与第三方集成的一部分,我需要使用C#对一些字符串信息进行UTF8编码,以便通过多部分表单将其发送到目标服务器。 问题是,他们拒绝了我的一些提交,可能是因为我没有正确编码其内容。
现在,我正在尝试弄清楚破折号(-)或连字符(-)如何被目标服务器接收或解释为?~@~S(是的,这是一个由5个字符组成的字符串,不是你的浏览器出错)。 不幸的是,我对Encoding.UTF8.GetBytes()的理解还不够深入,无法确定如何使用字节数组开始识别问题可能出在哪里。
如果有人能提供任何提示或建议,我将非常感激。 到目前为止,我的唯一朋友是MSDN,但帮助也不大。 更新1:经过更多的挖掘,我发现使用System.Web.HttpUtility.UrlEncode()对EM DASH字符(“—”)进行编码,将会将其十六进制编码为“%e2%80%94”。
我目前正在使用HttpWebRequest post发送此信息,并具有“application / x-www-form-urlencoded”类型的内容 - 这可能是问题所在吗? 如果是这样,那么编码一系列名称-值对的正确方法是什么,其中值可能包含Unicode字符,以便被期望UTF-8请求的服务器理解?

从那个结果来看,我猜测您可能正在将 utf8 编码的 em 破折号的结果转换为 ascii 编码。 - Joshua
即使编码错误,一个字符的破折号被翻译成五个字符的序列的可能性非常小。这很可能不仅是编码问题。 - Simon Mourier
@Joshua:我认为你已经接近问题的核心了。我刚刚在原帖中添加了一些更多的信息更新。 - Mass Dot Net
很遗憾,我本应选择application/octet-stream并假设它在两端都是正确的格式,所以我无法再帮助你了。 - Joshua
2个回答

3
byte[] test = System.Text.Encoding.UTF8.GetBytes("-");

应该给你

test[0] = 0x2D (45 as integer).  

请确认将0x2D发送至目标服务器。


1
Wireshark对于这种东西非常有帮助。 - Marlon
我以前从未使用过Wireshark,但我们的首席开发人员非常熟练地使用Fiddler。我一回到办公室就会尝试这个--感谢您的提示。 - Mass Dot Net
Wireshark的安装非常简单。它允许您查看发往服务器的数据包。您可以以多种方式过滤数据,以避免在数据中迷失。 - Chauncat
顺便问一下,正确输出上述信息的C#代码是什么(test[0] = 0x2D (45作为整数))? - Mass Dot Net
我使用这个函数将字节数组转换为十六进制字符串public static string BtyeToHexString(byte[] in_record, int startIndex, int count) { string hexString = "";if (startIndex + count <= in_record.Length) { for (int i = startIndex; i < startIndex + count; i++) { hexString += in_record[i].ToString("X2") + " "; } } return hexString;} - Chauncat
问题最终是目标服务器的问题:他们对POST请求进行了双重URL解码。然而,使用GetBytes()准备测试用例对于向他们展示工作未被正确传输非常有价值。 - Mass Dot Net

1
您可能需要在Content-Type头中添加“charset=utf-8”参数。您也可以使用Content-Encoding头来设置编码,但是这已经不再推荐使用了。头应包含以下内容:

Content-Type: multipart/form-data; charset=utf-8

否则,Web服务器将无法识别您的字节为UTF-8字节,因此会误解它们。

你说得对,我在发送多部分表单时目前没有明确定义内容编码类型。我刚刚给第三方发了一封电子邮件,询问他们是否知道默认的预期内容类型是什么 - 他们能轻松识别这个吗?我想他们正在运行微软服务器(IIS)。 - Mass Dot Net
UTF-8不是一个有效的Content-Encoding值。该头部用于指示负载(payload)的压缩方式,而不是用于指示字符集。 - dkarp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接