2010-07-26 23 views
0

因此,Twitter將其身份驗證方式更改爲OAuth,我終於別無選擇,只能更新我的應用程序。我得到了Twitter的工作(所以我的應用程序中保存了很多OAuth信息)。現在我必須讓TwitPic API再次運行。有沒有那個處理,我發現了OAuth的庫,所以我有手基於什麼我發現這裏做到這一點:將TwitPic API cURL示例移植到C#,多部分數據?

http://dev.twitpic.com/docs/2/upload/

我緩慢而穩步地到達那裏,我認爲。我不是這方面的專家,但我得到了他們的其他API調用: http://dev.twitpic.com/docs/2/users_show 它工作的魅力,雖然它不是多部分數據與圖像那裏。

我已經做了一些更多的研究並實現了我使用OAuth做的很好的Twitterizer框架,它爲我做了很多工作,即簽署每個請求,並且只要求我傳入一些OAuth令牌。所以我注意到上面爲TwitPic上傳的方法調用要求以相同的方式進行簽名,這是困難的部分:獲取它的簽名並使用webrequest傳遞它。

哪一個也讓我感到困惑,他們說OAuth echo部分的簽名看起來像是在一個頭文件中傳遞的,這與使用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"); 
       } 
      } 
     } 
    } 

回答

0

這裏是關於Twipli API的包裝,可以讓你做到這一點的變化。我唯一的問題是,我無法讓它響應第三方處理返回數據的結果。然而,它發佈到Twitter並正確上傳圖像。如此多的人頭比一人好,所以如果你想出一個解決方案讓我知道。

protected void Button1_Click(object sender, EventArgs e) 
{ 

    string ct = img.PostedFile.ContentType.ToString(); 
    string usertoken = Session["usrToken"].ToString(); 
    string userSecret = Session["usrSecret"].ToString(); 
    string conkey = Session["ConsumerKey"].ToString(); 
    string consecret = Session["ConsumerSecret"].ToString(); 
    string twitkey = Session["twitpickey"].ToString(); 

    string _m = m.Text; // This takes the Tweet to be posted 


    HttpPostedFile myFile = img.PostedFile; 
    string fileName = myFile.FileName.ToString(); 

    int nFileLen = myFile.ContentLength; 
    byte[] myData = new byte[nFileLen]; 
    myFile.InputStream.Read(myData, 0, nFileLen); 

    TwitPic tw = new TwitPic(); 
    upres.Text = tw.UploadPhoto(myData, ct, _m, fileName, twitkey, usertoken, userSecret, conkey, consecret).ToString(); 
    Response.Redirect("twittercb.aspx?oauth_verifier=none"); 
} 
public class TwitPic 
{ 
    private const string TWITPIC_UPLADO_API_URL = "http://api.twitpic.com/2/upload"; 
    private const string TWITPIC_UPLOAD_AND_POST_API_URL = "http://api.twitpic.com/1/uploadAndPost"; 
    /// 
    /// Uploads the photo and sends a new Tweet 
    /// 
    /// <param name="binaryImageData">The binary image data. 
    /// <param name="tweetMessage">The tweet message. 
    /// <param name="filename">The filename. 
    /// Return true, if the operation was succeded. 
    public string UploadPhoto(byte[] binaryImageData, string ContentType, string tweetMessage, string filename, string tpkey, string usrtoken, string usrsecret, string contoken, string consecret) 
    {    
     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 = ContentType; 
     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}\"", "key")); 
     contents.AppendLine(); 
     contents.AppendLine(tpkey); 

     contents.AppendLine(header); 
     contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "consumer_token")); 
     contents.AppendLine(); 
     contents.AppendLine(contoken); 

     contents.AppendLine(header); 
     contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "consumer_secret")); 
     contents.AppendLine(); 
     contents.AppendLine(consecret); 

     contents.AppendLine(header); 
     contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "oauth_token")); 
     contents.AppendLine(); 
     contents.AppendLine(usrtoken); 

     contents.AppendLine(header); 
     contents.AppendLine(String.Format("Content-Disposition: form-data; name=\"{0}\"", "oauth_secret")); 
     contents.AppendLine(); 
     contents.AppendLine(usrsecret); 

     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; 

     string mediaurl = ""; 
     try 
     { 
      using (Stream requestStream = request.GetRequestStream()) // this is where the bug is due to not being able to seek. 
      {   
       requestStream.Write(bytes, 0, bytes.Length); // No problem the image is posted and tweet is posted 
       requestStream.Close();      
       using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) // here I can't get the response 
       { 
        using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
        { 
         string result = reader.ReadToEnd(); 

         XDocument doc = XDocument.Parse(result); // this shows no root elements and fails here 

         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; 
         mediaurl = rsp.Element("mediaurl").Value; 
         return mediaurl;        
        } 
       } 

      } 
     } 
     catch (Exception ex) 
     { 
      ex.ToString(); 
     } 
     return mediaurl; 
    } 

} 
1

該修復其實很簡單。問題是您要發佈到的URL。在您的線路:

private const string TWITPIC_UPLOAD_AND_POST_API_URL = "http://api.twitpic.com/1/uploadAndPost"; 

您需要更改到

private const string TWITPIC_UPLOAD_AND_POST_API_URL = "http://api.twitpic.com/1/uploadAndPost.xml"; 

OR

private const string TWITPIC_UPLOAD_AND_POST_API_URL = "http://api.twitpic.com/1/uploadAndPost.json"; 

這會給你響應類型。您仍然需要更改與您使用XDocument解析結果相關的代碼部分。根據上面使用的URL,響應將是XML或JSON。您的示例適用於XML,但結果代碼與您正在查找的內容不相符。如果要查看結果代碼示例,可以在http://dev.twitpic.com/docs/1/uploadAndPost/

查看它例如,刪除以下行。

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; 
mediaurl = rsp.Element("mediaurl").Value; 

然後用

mediaurl = doc.Element("image").Element("url").Value; 

更換或者你可以通過調試器運行JSON。如果有人需要它並請求,我可以完成完整的代碼。

+0

此回覆對Brandons問題發佈於12/24/10 – 2011-03-26 22:24:33