2013-04-07 34 views
7

Tôi đang cố đăng trạng thái Twitter từ ứng dụng web của mình, sử dụng RestSharp. Các mã sau hoạt động hoàn hảo:RestSharp và Twitter API 1.1: Làm thế nào để tôi có văn bản cập nhật trạng thái URLEncode chính xác?

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); 

Tuy nhiên, mã này không thành công với một lỗi xác thực nếu tôi bao gồm bất kỳ các ký tự sau trong văn bản trạng thái: ! * ' ()

Qua một nhiều of this forum lưới vét, tôi đã suy luận rằng đây là một cái gì đó để làm với mã hóa chữ ký OAuth không phù hợp với mã hóa của các tham số POST. Tôi tìm thấy this question on SO, nhưng tìm kiếm các vấn đề RestSharp trên GitHub cho thấy không có gì hữu ích.

Tôi có thể thấy some code in the RestSharp source (UrlEncodeRelaxed) dường như mã hóa thủ công bộ ký tự cụ thể đó để tuân thủ thông số mã hóa OAuth, vì vậy tôi đã cố gắng mã hóa thủ công các ký tự đó trong trạng thái của tôi theo cách tương tự (với mã được lấy từ RestSharp) trước khi chuyển nó vào, ví dụ:

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]); 

Nhưng điều này không có tác dụng (tôi vẫn nhận được lỗi xác thực).

Điều gì thực sự là vấn đề ở đây và tôi nên làm gì để mã hóa chính xác trạng thái? Hay đây là lỗi RestSharp?

+0

Bạn có tìm thấy giải pháp hoặc làm việc xung quanh không? Tôi đang cố gắng giải quyết vấn đề này ngay bây giờ. –

+0

@Michael_B Không, xin lỗi: Tôi bắt đầu xem xét nó, nhưng đã không nhận được rất xa trước khi các ưu tiên khác có trong cách. –

+0

Tôi đã kết thúc bằng cách sử dụng Linq2Twitter để cập nhật trạng thái. Nó hoạt động với v1.1 của API Twitter. Tôi không bao giờ tìm thấy một cách nào đó xung quanh các vấn đề OAuth của RestSharp. –

Trả lời

2

Bạn đã thử sử dụng lớp HttpUtility được tích hợp trong .NET Framework chưa? Bạn có thể tìm thấy nó trong không gian tên System.Web.

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

MSDN


này chắc chắn là một vấn đề RestSharp ... Tôi chơi đùa với nó trong một thời gian và vấn đề là không có anyway để vô hiệu hóa mã hóa tiêu chuẩn phần trăm .. .

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); 


} 

Trong Fiddler tôi đã theo dõi các yêu cầu đi lên Twitter ... và đây là những gì tôi tìm thấy ...

01.235.
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 

Vấn đề với yêu cầu Http, là phần yêu cầu của chúng tôi ... có giá trị mà tôi đã cung cấp chưa được chạm ... thì Twitter sẽ nhận ra thông báo và cập nhật trạng thái của chúng tôi cho chúng tôi ....

status=Dogs%252C%2520Cats%2520%2526%2520Mice <--- Altered by RestSharp 
status=Dogs%2C%20Cats%20%26%20Mice   <--- What I initially sent 
+0

Vấn đề là phương thức mã hóa * không * làm cho nó hoạt động: được xây dựng trong, bằng tay hoặc bằng cách khác. Điều này khiến tôi tin rằng đó là một vấn đề RestSharp nội bộ. Vẫn chưa giải quyết được nó, mặc dù ... –

+0

Tôi vừa kiểm tra tất cả ... và có .. đó là một vấn đề RestSharp ... Cập nhật câu trả lời của tôi ở trên để giải thích những gì đang xảy ra ... –

+0

Điều này hữu ích , cảm ơn - tôi sẽ kiểm tra nguồn RestSharp và xem liệu tôi có thể tìm ra một bản sửa lỗi hay không. –

Các vấn đề liên quan