当我终于得到一些与Twitter的API交谈的ASP.NET代码时,我很高兴,它在测试时表现完美,在我的帐户上创建任意长度的推文,提及@usernames,甚至每分钟发送10次到同一个帐户。
但现在我收到HTTP状态代码401和这个JSON:
{"errors":[{"code":32, "message":"Could not authenticate you."}]}
这些错误几乎是随机的,直到我发现了一些东西。在我之前的任何测试中,我似乎从未使用过标点符号!现在,带有撇号,括号和感叹号的推文被拒绝了 - 但逗号,连字符和问号都没问题。
本节的第一行必须是我的问题区域:
Dim postBody = "media_ids=" & TwitterMediaID & "&status=" & Uri.EscapeDataString(TextOfTheTweet)
System.Net.ServicePointManager.Expect100Continue = False
Dim request As System.Net.HttpWebRequest = System.Net.WebRequest.Create(TwitterStatusPostURL)
request.Headers.Add("Authorization", OAuthSignature)
request.Method = "POST"
request.ContentType = "application/x-www-form-urlencoded"
我想Uri.EscapeDataString()
是编码的错误选择,虽然我非常感谢original author这个代码因为没有它们我会无处可去!
这个函数接受Apotrophe' exclamation! brackets() question? fullstop. comma, colon: semicolon; hyphen-
并返回Apotrophe'%20exclamation!%20brackets()%20question%3F%20fullstop.%20comma%2C%20colon%3A%20semicolon%3B%20hyphen-
,这显然不是Twitter想要看到的(或者更确切地说,这与OAuth有关吗?)。
据the wonderful table in this SO question说,没有什么可以编码感叹号?!
我应该能够找到一个更好的功能来自己使用,但我很想知道这里的问题到底是什么,并且确信我理解哪种编码功能适合哪个工作。这也需要记录在未来的标点符号程序员中。
所以问题可归纳为:为什么这个功能不是正确的选择,我们应该使用什么?谢谢。
Twitter API文档(截至2019年3月)说我必须使用RFC 3986。
我使用的旧版dotNET似乎不完全支持Uri.EscapeDataString()
中的RFC 3986,我需要dotNET v4.5或更高版本来解决这个问题。
This answer to a similar question说我可以用这个单行程单自己组成四个缺失的标点元素:
Regex.Replace(Uri.EscapeDataString(s), "[\!*\'\(\)]", Function(m) Uri.HexEscape(Convert.ToChar(m.Value(0).ToString())))
就个人而言,我对一个更易阅读的版本感到满意:
Uri.EscapeDataString(s).Replace("!", "%21").Replace("'", "%27").Replace("(", "%28").Replace(")", "%29")