I'm trying to post a Twitter status from my web app, using RestSharp. The following code works perfectly:
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);
However, this code fails with an authentication error if I include any of the following characters in the status text: ! * ' ( )
Through a lot of forum trawling, I've deduced that this is something to do with the OAuth signature encoding not matching the encoding of the POST parameters. I found this question on SO, but searching the RestSharp issues on GitHub reveals nothing helpful.
I can see some code in the RestSharp source (UrlEncodeRelaxed
) which seems to be manually encoding that particular set of characters to comply with the OAuth encoding specs, so I've tried manually encoding those characters in my status in the same way (with code taken from RestSharp) before passing it in, e.g:
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]);
But this doesn't work either (I still get the authentication error).
What actually is the problem here, and what should I be doing to correctly encode the status? Or is this a RestSharp bug?
Have you tried using the HttpUtility class built in to the .NET Framework? You can find it in the System.Web namespace.
string urlEncodedText = HttpUtility.UrlEncode("Your text goes here");
MSDN
This is definitely a RestSharp issue... I played around with it for a while and the problem is that there isn't anyway to disable the standard percent encoding...
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);
}
In Fiddler I've been monitoring the requests going to Twitter... and this is what I found...
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
The problem with the Http Request, is the body of our request... had the value I had supplied not been touched... then Twitter would have recognised the message and updated our status for us....
status=Dogs%252C%2520Cats%2520%2526%2520Mice <--- Altered by RestSharp
status=Dogs%2C%20Cats%20%26%20Mice <--- What I initially sent
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With