因此,Twitter将其身份验证方式改为
OAuth
,我最终别无选择,只能更新我的应用程序。我让Twitter的东西正常工作了(所以我在应用程序中保存了一些很好的OAuth信息)。现在我要拿到
TwitPic
API再次工作。没有处理我找到的OAuth的库,因此我必须根据我在这里找到的内容手动完成它:
http://dev.twitpic.com/docs/2/upload/
我想,我正在缓慢但肯定地到达那里。我无论如何都不是这方面的专家,但我得到了他们的另一个API调用:
http://dev.twitpic.com/docs/2/users_show
它就像一个魔咒,虽然它不是包含图像的多部分数据。
我做了更多的研究,并意识到我正在使用的漂亮的推特器框架为我做了大量的工作,即签署每个请求,只需要我传入几位OAuth令牌。所以我注意到上面为TwitPic上传的方法调用要求以相同的方式签名,这是困难的部分:获得签名,然后使用webrequest传递。
这也是让我困惑的地方,他们说OAuth echo部分的签名似乎是在头中传递的,这与使用C#'s创建头相同吗
System.Net.WebHeaderCollection webhc = new System.Net.WebHeaderCollection();
?
我知道我必须做什么,以某种方式获得用我的OAuth令牌(序列化为JSON)调用的请求,构建一个签名,然后调用实际的API并将三个参数(JSON序列化)传递给它:键、消息、文件。
这个文件也让我大吃一惊,因为它是一个内存驻留文件,我不知道如何传递这个数据。我确实有一段来自旧TwitPic库的代码片段:
string fileContentType = "image/jpeg";
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令牌。唉。。。如果转向正确,我们将不胜感激。
发布完整性是我使用的旧上载文件方法:
public bool UploadPhoto(byte[] binaryImageData, string tweetMessage, string filename)
{
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";
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(header);
contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "password"));
contents.AppendLine();
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");
}
}
}
}