我正在尝试使用
RestSharp从我的网络应用发布Twitter状态.以下代码完美运行:
var status = "I am fine with posting this status."; var client = new RestClient("https://api.twitter.com"); // The OAuth keys/tokens/secrets are retrieved elsewhere client.Authenticator = OAuth1Authenticator.ForProtectedResource( _consumerKey,_consumerSecret,_accessToken,_accessTokenSecret ); var request = new RestRequest("/1.1/statuses/update.json",Method.POST); request.AddParameter("status",status,ParameterType.GetOrPost); var response = client.Execute(request);
但是,如果我在状态文本中包含以下任何字符,则此代码将失败并出现身份验证错误: *'()
通过大量的论坛拖网,我推断这与OAuth签名编码不匹配POST参数的编码有关.我找到了this question on SO,但在GitHub上搜索RestSharp问题没有任何帮助.
我可以看到some code in the RestSharp source(UrlEncodeRelaxed),它似乎是手动编码该特定字符集以符合OAuth编码规范,所以我尝试以相同的方式手动编码我的状态中的那些字符(代码取自RestSharp)传递它,例如:
var status = "I'm NOT fine with posting this status."; string[] UriRfc3986CharsToEscape = new[] { "!","*","'","(",")" }; string[] UriRfc3968EscapedHex = new[] { "%21","%2A","%27","%28","%29" }; for (var i = 0; i < UriRfc3986CharsToEscape.Length; i++) status = status.Replace(UriRfc3986CharsToEscape[i],UriRfc3968EscapedHex[i]);
但这也不起作用(我仍然得到身份验证错误).
实际上这里的问题是什么,我应该怎么做才能正确编码状态?或者这是一个RestSharp错误?
解决方法
您是否尝试过使用.NET Framework内置的HttpUtility类?您可以在System.Web命名空间中找到它.
string urlEncodedText = HttpUtility.UrlEncode("Your text goes here");
这绝对是一个RestSharp问题……我玩了一段时间,问题是无论如何都没有禁用标准百分比编码……
void Main() { var ProtectedChars = "0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A".Replace(" 0x","%").Split(','); var client = new RestClient("https://api.twitter.com"); client.Authenticator = OAuth1Authenticator.ForProtectedResource( "_consumerKey","_consumerSecret","_accessToken","_accessTokenSecret" ); var status = "Dogs,Cats & Mice"; string newStatus = string.Empty; foreach (char c in status) { var charBytes = Encoding.UTF8.GetBytes(c.ToString()); var tempText = string.Empty; for (int i = 0; i < charBytes.Count(); i++) { byte b = charBytes[i]; string hex = "%" + b.ToString("X2"); tempText += hex; } if (ProtectedChars.Any(x => x == tempText)) { newStatus += c; } else { newStatus += string.Format("{0:X2}",tempText); } } var request = new RestRequest("/1.1/statuses/update.json",Method.POST); request.AddParameter(new Parameter{ Name = "status",Type = ParameterType.GetOrPost,Value = newStatus } ); var response = client.Execute(request); }
在Fiddler我一直在监视转发Twitter的请求……这就是我发现的……
POST https://api.twitter.com/1.1/statuses/update.json HTTP/1.1 Authorization: /* auth data */ Accept: application/json,application/xml,text/json,text/x-json,text/javascript,text/xml User-Agent: RestSharp/104.4.0.0 Content-Type: application/x-www-form-urlencoded Host: api.twitter.com Content-Length: 44 Accept-Encoding: gzip,deflate status=Dogs%252C%2520Cats%2520%2526%2520Mice
Http请求的问题是我们的请求的主体……如果我提供的价值没有被触及……那么Twitter就会识别该消息并更新我们的状态….
status=Dogs%252C%2520Cats%2520%2526%2520Mice <--- Altered by RestSharp status=Dogs%2C%20Cats%20%26%20Mice <--- What I initially sent