2010-07-26 1 views
0

Twitter에서 인증 방식을 OAuth으로 바 꾸었습니다. 결국 앱을 업데이트 할 수 밖에 없었습니다. 나는 트위터가 작동하도록했다. (그래서 나는 나의 애플리케이션에 저장된 OAuth 정보를 가지고있다.) 이제 TwitPic API를 다시 작동시켜야합니다. 이 내가 찾은 OAuth를 처리 더 라이브러리는 없습니다, 그래서 내가 여기 내용에 따라 손으로 그것을 할 데 : 나는 천천히 그러나 확실하게이 무엇입니까TwitPic API cURL 예제를 C#, multipart data로 이식 하시겠습니까?

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

나는 생각한다. 나는 어떤 종류의 물건이라도이 종류의 전문가가 아니다. 그러나 나는 그들의 다른 API 콜을 가지고있다. http://dev.twitpic.com/docs/2/users_show 그것은 이미지와 함께 멀티 파트 데이터가 아니지만 매력처럼 작동하고있다.

나는 더 많은 연구를 해보았으며, OAuth를 사용하여 멋진 Twitterizer 프레임 워크를 실현했다. 즉, 각 요청에 서명하고 OAuth 토큰을 약간만 전달하면된다. 그래서 TwitPic에 업로드하기위한 위 메소드 호출이 같은 방식으로 서명되어야한다는 것을 알아 챘습니다. 그것은 어려운 부분입니다 : 서명하고 웹 요청을 사용하여 전달하는 것입니다.

나도 혼란 스럽다. 그들은 OAuth 에코 부분이 보이는 헤더에 전달되는 서명을 말하는데, 이것은 C#의 System.Net.WebHeaderCollection webhc = new System.Net.WebHeaderCollection();을 사용하여 헤더를 만드는 것과 동일하다.

나는 OAuth 토큰 (JSON에 직렬화)으로 요청한 요청을 받고 서명을 작성한 다음 실제 API를 호출하고 세 개의 매개 변수 (JSON Serialized)를 전달한다. 키, 메시지, 파일.

파일이 메모리 상주 파일이므로이 데이터를 전달하는 방법을 모르겠다.

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을하려고하고 있다는 것이다 : 나는 이전 TwitPic 라이브러리에서 코드를해야합니까. FileContentType 등을 작성하여 StringBuilder 내용 객체에 추가하는 작업은 필자가 필요로하는 것보다 훨씬 많은 수동 작업처럼 보입니다.

내가 파일, 메시지 및 OAuth 토큰을 전달하는 Twitter의 새로운 승인을위한 TwitPic API가 있었으면 좋겠습니다. 아아 ... 올바른 방향으로 조종하는 것이 크게 감사 할 것입니다.

다음
// <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 래퍼의 변형이다 완성도 게시

내가 가지고있는 기존의 파일 업로드 방법이다. 내가 가진 유일한 문제는 반환 된 데이터의 제 3 자 조작 결과에 응답 할 수 없다는 것입니다. 그러나 그것은 트위터에 게시하고 이미지를 올바르게 업로드합니다. 많은 머리가 하나보다 낫기 때문에 해결책을 생각해 내면 알려주세요.

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

또는

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 Problem에 게시 된 것입니다 12/24/10 –