【问题标题】:RestSharp and Twitter API 1.1: How do I correctly URLEncode status update text?RestSharp 和 Twitter API 1.1:如何正确 URLEncode 状态更新文本?
【发布时间】:2013-03-29 12:13:10
【问题描述】:

我正在尝试使用 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 错误?

【问题讨论】:

  • 您找到解决方案或解决方法了吗?我现在正在努力解决这个问题。
  • @Michael_B 不,抱歉:我开始研究它,但没走多远,其他优先事项就出现了。
  • 我最终使用 Linq2Twitter 进行状态更新。它适用于 Twitter API 的 v1.1。我从来没有找到解决 RestSharp 的 OAuth 问题的方法。

标签: c# oauth twitter twitter-oauth restsharp


【解决方案1】:

您是否尝试过使用 .NET Framework 中内置的 HttpUtility 类?您可以在 System.Web 命名空间中找到它。

string urlEncodedText = HttpUtility.UrlEncode("Your text goes here");

MSDN


这绝对是一个 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

【讨论】:

  • 关键是 no 的编码方法使其工作:内置,手动或其他。这让我相信这是一个内部 RestSharp 问题。不过还没解决……
  • 我刚刚检查了所有内容......是的......这是一个 RestSharp 问题......更新了我上面的答案以解释发生了什么......
  • 这很有用,谢谢——我要去看看 RestSharp 源代码,看看能不能找到解决办法。
  • 尝试用断点封装 status 字符串,在它的 mutator / setter 上设置一个断点。希望这会引导你直接找到改变值的任何方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 2012-01-11
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
相关资源
最近更新 更多