【发布时间】:2014-04-09 00:55:11
【问题描述】:
C# Windows 窗体在 Twitter 上发布状态更新
我已经尝试了所有我能找到的解决方案,并拼凑了以下代码,它总是给出 401 授权错误。
当我在 twitter 中设置一个 twitter 应用程序时,它要求一个回调 url,我正在我的本地机器上开发它,并且需要使用 windows 窗体,以便推文可以从我的本地数据库中获取数据。我只想从我自己的帐户发推文,但在我添加新项目时从我的数据库中获取数据以插入推文。
我尝试将编码更改为 UTF8(将之前的字符串定义注释掉以显示位置),读完这可能是某个地方的问题。
我不知道授权是否有问题,因为我拥有所有必需的密钥,或者它是否与回调 url 有关,如果是这样,我可以将什么用于没有网站的 windows 窗体客户端。
如果我将 dev.twitter 站点中的 CURL 粘贴到我的浏览器中,我会在使用 https://api.twitter.com/1.1/statuses/update.json 时收到“错误的身份验证数据”(默认为 1 并给出一条消息,指出这已被弃用)。我为回调 url 输入的网站是我的,但我不知道那里是否需要代码才能使这个测试起作用。
任何帮助将不胜感激我已经尝试解决这个问题一周了。
public static void anotherTweet(string status)
{
//GS - Get the oAuth params
//string status = status;
string postBody = "status=" +
Uri.EscapeDataString(status);
string oauth_consumer_key = "xxx";
//string oauth_nonce = Convert.ToBase64String(
//new ASCIIEncoding().GetBytes(
// DateTime.Now.Ticks.ToString()));
string oauth_nonce = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(DateTime.Now.Ticks.ToString()));
string oauth_signature_method = "HMAC-SHA1";
string oauth_token =
"xxx";
string oauth_version = "1.0";
TimeSpan ts = DateTime.UtcNow -
new DateTime(1970, 1, 1, 0, 0, 0, 0);
string oauth_timestamp =
Convert.ToInt64(ts.TotalSeconds).ToString();
//string oauth_version = "1.0";
//GS - When building the signature string the params
//must be in alphabetical order. I can't be bothered
//with that, get SortedDictionary to do it's thing
SortedDictionary<string, string> sd =
new SortedDictionary<string, string>();
sd.Add("status", status);
sd.Add("oauth_version", oauth_version);
sd.Add("oauth_consumer_key", oauth_consumer_key);
sd.Add("oauth_nonce", oauth_nonce);
sd.Add("oauth_signature_method", oauth_signature_method);
sd.Add("oauth_timestamp", oauth_timestamp);
sd.Add("oauth_token", oauth_token);
//GS - Build the signature string
string baseString = String.Empty;
baseString += "POST" + "&";
baseString += Uri.EscapeDataString(
"https://api.twitter.com/1.1/statuses/update.json")
+ "&";
foreach (KeyValuePair<string,string> entry in sd)
{
baseString += Uri.EscapeDataString(entry.Key +
"=" + entry.Value + "&");
}
//GS - Remove the trailing ambersand char, remember
//it's been urlEncoded so you have to remove the
//last 3 chars - %26
baseString =
baseString.Substring(0, baseString.Length - 3);
//GS - Build the signing key
string consumerSecret =
"xxx";
string oauth_token_secret =
"xxx";
string signingKey =
Uri.EscapeDataString(consumerSecret) + "&" +
Uri.EscapeDataString(oauth_token_secret);
//GS - Sign the request
HMACSHA1 hasher = new HMACSHA1(
new ASCIIEncoding().GetBytes(signingKey));
//string signatureString = Convert.ToBase64String(
//hasher.ComputeHash(
// new ASCIIEncoding().GetBytes(baseString)));
string signatureString = Convert.ToBase64String(
hasher.ComputeHash(
System.Text.Encoding.UTF8.GetBytes(baseString)));
//GS - Tell Twitter we don't do the 100 continue thing
ServicePointManager.Expect100Continue = false;
//GS - Instantiate a web request and populate the
//authorization header
HttpWebRequest hwr =
(HttpWebRequest)WebRequest.Create(
@"https://api.twitter.com/1.1/statuses/update.json");
string authorizationHeaderParams = String.Empty;
authorizationHeaderParams += "OAuth ";
authorizationHeaderParams += "oauth_nonce=" + "\"" +
Uri.EscapeDataString(oauth_nonce) + "\",";
authorizationHeaderParams +=
"oauth_signature_method=" + "\"" +
Uri.EscapeDataString(oauth_signature_method) +
"\",";
authorizationHeaderParams += "oauth_timestamp=" + "\"" +
Uri.EscapeDataString(oauth_timestamp) + "\",";
authorizationHeaderParams += "oauth_consumer_key="
+ "\"" + Uri.EscapeDataString(
oauth_consumer_key) + "\",";
authorizationHeaderParams += "oauth_token=" + "\"" +
Uri.EscapeDataString(oauth_token) + "\",";
authorizationHeaderParams += "oauth_signature=" + "\""
+ Uri.EscapeDataString(signatureString) + "\",";
//authorizationHeaderParams += "oauth_version=" + "\"" +
//Uri.EscapeDataString(oauth_version) + "\"";
hwr.Headers.Add(
"Authorization", authorizationHeaderParams);
//GS - POST off the request
hwr.Method = "POST";
hwr.ContentType = "application/x-www-form-urlencoded";
Stream stream = hwr.GetRequestStream();
//byte[] bodyBytes =
//new ASCIIEncoding().GetBytes(postBody);
byte[] bodyBytes = System.Text.Encoding.UTF8.GetBytes(postBody);
stream.Write(bodyBytes, 0, bodyBytes.Length);
stream.Flush();
stream.Close();
//GS - Allow us a reasonable timeout in case
//Twitter's busy
hwr.Timeout = 3 * 60 * 1000;
try
{
HttpWebResponse rsp = hwr.GetResponse()
as HttpWebResponse;
//GS - Do something with the return here...
}
catch (WebException e)
{
MessageBox.Show(e.Message);
}
}
【问题讨论】:
-
OAUTH 可能难以排除故障。我强烈建议您使用其中一个已建立的 OAuth 库,而不是滚动您自己的 OAuth 代码。这将使您专注于您的应用程序,而不是调试 OAuth。我会在dotnetopenauth.net 上查看 DotNetOpenAuth
标签: c# windows winforms twitter status