所以 Twitter 将其身份验证方式更改为OAuth,我最终别无选择,只能更新我的应用程序。我得到了 Twitter 的东西(所以我的应用程序中有很多保存的 OAuth 信息)。现在我必须让TwitPic API 再次工作。没有处理我发现的 OAuth 的库,所以我必须根据我在这里找到的内容手动完成:
http://dev.twitpic.com/docs/2/upload/
我认为我正在缓慢但肯定地到达那里。无论如何,我都不是这类东西的专家,但我得到了他们的其他 API 调用: http ://dev.twitpic.com/docs/2/users_show 它就像一个魅力,虽然这不是多部分的有图像的数据。
我做了一些更多的研究,并意识到我在执行 OAuth 时使用的不错的 Twitterizer 框架为我做了很多工作,即签署每个请求,并且只需要我传递一些 OAuth 令牌。所以我注意到上面为 TwitPic 上传的方法调用需要以相同的方式签名,这是困难的部分:对其进行签名,然后使用 webrequest 传递它。
这也是让我感到困惑的地方,他们说 OAuth 回显部分的签名似乎是在标头中传递的,这与使用 C# 创建标头相同System.Net.WebHeaderCollection webhc = new System.Net.WebHeaderCollection();
吗?
我知道我必须做什么,以某种方式使用我的 OAuth 令牌调用请求(序列化为 JSON),构建签名,然后调用实际 API 并将三个参数传递给它(JSON 序列化):密钥、消息、文件。
该文件也让我感到困惑,因为它是一个内存驻留文件,我不知道如何传递这些数据。我确实有一个来自较旧 TwitPic 库的代码片段:
string fileContentType = "image/jpeg";//GetImageContentType(filename);
string fileHeader = String.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"", "media", filename);
string fileData = Encoding.GetEncoding(encoding).GetString(binaryImageData);
contents.AppendLine(fileHeader);
contents.AppendLine(String.Format("Content-Type: {0}", fileContentType));
contents.AppendLine();
contents.AppendLine(fileData);
问题是我正在尝试使用 JSON 来完成所有这些工作。构建 fileContentType 等以将其全部附加到 StringBuilder 内容对象似乎比我需要的手动工作要多得多。
我希望 Twitter 的新授权有一个 TwitPic API,我将文件、消息和 OAuth 令牌传递给它。唉...任何朝着正确方向的转向将不胜感激。
为了完整起见,我发布了旧的上传文件方法:
// <summary>
// Uploads the photo and sends a new Tweet
// </summary>
// <param name="binaryImageData">The binary image data.</param>
// <param name="tweetMessage">The tweet message.</param>
// <param name="filename">The filename.</param>
// <returns>Return true, if the operation was succeded.</returns>
public bool UploadPhoto(byte[] binaryImageData, string tweetMessage, string filename)
{
// Documentation: http://www.twitpic.com/api.do
string boundary = Guid.NewGuid().ToString();
string requestUrl = String.IsNullOrEmpty(tweetMessage) ? TWITPIC_UPLADO_API_URL : TWITPIC_UPLOAD_AND_POST_API_URL;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
string encoding = "iso-8859-1";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
request.Method = "POST";
string header = string.Format("--{0}", boundary);
string footer = string.Format("--{0}--", boundary);
StringBuilder contents = new StringBuilder();
contents.AppendLine(header);
string fileContentType = "image/jpeg";//GetImageContentType(filename);
string fileHeader = String.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"", "media", filename);
string fileData = Encoding.GetEncoding(encoding).GetString(binaryImageData);
contents.AppendLine(fileHeader);
contents.AppendLine(String.Format("Content-Type: {0}", fileContentType));
contents.AppendLine();
contents.AppendLine(fileData);
contents.AppendLine(header);
contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "username"));
contents.AppendLine();
//contents.AppendLine(this.Username);
contents.AppendLine(header);
contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "password"));
contents.AppendLine();
//contents.AppendLine(this.Password.ToInsecureString());
if (!String.IsNullOrEmpty(tweetMessage))
{
contents.AppendLine(header);
contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "message"));
contents.AppendLine();
contents.AppendLine(tweetMessage);
}
contents.AppendLine(footer);
byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(contents.ToString());
request.ContentLength = bytes.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string result = reader.ReadToEnd();
XDocument doc = XDocument.Parse(result);
XElement rsp = doc.Element("rsp");
string status = rsp.Attribute(XName.Get("status")) != null ? rsp.Attribute(XName.Get("status")).Value : rsp.Attribute(XName.Get("stat")).Value;
return status.ToUpperInvariant().Equals("OK");
}
}
}
}