2011-02-04 9 views
5

FacebookのJavascript APIを使用して画像をユーザーの壁に投稿する必要があるアプリケーションを開発しています。 画像のデータを「マルチパート/フォームデータ」として投稿する必要があるため、アプリのその部分は私が知る限りサーバー側にする必要があります。グラフAPIを使用して.NETからFacebookの壁に画像を投稿する

注:「投稿」を使用した単純なバージョンではなく、実際の「写真」方法です。

http://graph.facebook.com/me/photos

私は二つの問題、.NETおよびFacebookの問題直面していると思う:

Facebookの問題:私はすべてのパラメータが/マルチパートとして送信する必要がある場合はかなりよく分からないがフォームデータ(access_tokenとメッセージを含む)。唯一のコード例は、cUrlユーティリティ/アプリケーションを使用しています。

.NETの問題: .NETからmultipart/form-dataリクエストを発行したことはありません.Netが自動的にmime-partsを作成するかどうか、または一部でパラメータをエンコードする必要があるかどうかはわかりません特別な方法。

グラフAPIから得られる唯一のエラー応答は「400 - 悪い要求」なので、デバッグは少し難しいです。 以下は、私がこの質問を書くことにしたときのコードです(はい、少し冗長です:-)

究極の答えは、もちろん.NETから画像を投稿するサンプルスニペットです少ないために。

string username = null; 
string password = null; 
int timeout = 5000; 
string requestCharset = "UTF-8"; 
string responseCharset = "UTF-8"; 
string parameters = ""; 
string responseContent = ""; 

string finishedUrl = "https://graph.facebook.com/me/photos"; 

parameters = "access_token=" + facebookAccessToken + "&message=This+is+an+image"; 
HttpWebRequest request = null; 
request = (HttpWebRequest)WebRequest.Create(finishedUrl); 
request.Method = "POST"; 
request.KeepAlive = false; 
//application/x-www-form-urlencoded | multipart/form-data 
request.ContentType = "multipart/form-data"; 
request.Timeout = timeout; 
request.AllowAutoRedirect = false; 
if (username != null && username != "" && password != null && password != "") 
{ 
    request.PreAuthenticate = true; 
    request.Credentials = new NetworkCredential(username, password).GetCredential(new Uri(finishedUrl), "Basic"); 
} 
//write parameters to request body 
Stream requestBodyStream = request.GetRequestStream(); 
Encoding requestParameterEncoding = Encoding.GetEncoding(requestCharset); 
byte[] parametersForBody = requestParameterEncoding.GetBytes(parameters); 
requestBodyStream.Write(parametersForBody, 0, parametersForBody.Length); 
/* 
This wont work 
byte[] startParm = requestParameterEncoding.GetBytes("&source="); 
requestBodyStream.Write(startParm, 0, startParm.Length); 
byte[] fileBytes = File.ReadAllBytes(Server.MapPath("images/sample.jpg")); 
requestBodyStream.Write(fileBytes, 0, fileBytes.Length); 
*/ 
requestBodyStream.Close(); 

HttpWebResponse response = null; 
Stream receiveStream = null; 
StreamReader readStream = null; 
Encoding responseEncoding = System.Text.Encoding.GetEncoding(responseCharset); 
try 
{ 
    response = (HttpWebResponse) request.GetResponse(); 
    receiveStream = response.GetResponseStream(); 
    readStream = new StreamReader(receiveStream, responseEncoding); 
    responseContent = readStream.ReadToEnd(); 
} 
finally 
{ 
    if (receiveStream != null) 
    { 
     receiveStream.Close(); 
    } 
    if (readStream != null) 
    { 
     readStream.Close(); 
    } 
    if (response != null) 
    { 
     response.Close(); 
    } 
} 

答えて

4

バイナリデータをアップロードする方法の例を示します。しかし、/ me/photosへのアップロードは画像を壁に公開しません:(画像はあなたのアプリのアルバムに保存されています。私はフィードでそれを発表する方法についていません。アルバムを作成する方法は見つけられませんでした(サイトを介して画像をアップロードするときにユーザーが作成します)フィッツのコード@使用してクラスのメソッドをクリーンアップ。

{ 
    string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); 
    uploadRequest = (HttpWebRequest)WebRequest.Create(@"https://graph.facebook.com/me/photos"); 
    uploadRequest.ServicePoint.Expect100Continue = false; 
    uploadRequest.Method = "POST"; 
    uploadRequest.UserAgent = "Mozilla/4.0 (compatible; Windows NT)"; 
    uploadRequest.ContentType = "multipart/form-data; boundary=" + boundary; 
    uploadRequest.KeepAlive = false; 

    StringBuilder sb = new StringBuilder(); 

    string formdataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n"; 
    sb.AppendFormat(formdataTemplate, boundary, "access_token", PercentEncode(facebookAccessToken)); 
    sb.AppendFormat(formdataTemplate, boundary, "message", PercentEncode("This is an image")); 

    string headerTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n"; 
    sb.AppendFormat(headerTemplate, boundary, "source", "file.png", @"application/octet-stream"); 

    string formString = sb.ToString(); 
    byte[] formBytes = Encoding.UTF8.GetBytes(formString); 
    byte[] trailingBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); 

    long imageLength = imageMemoryStream.Length; 
    long contentLength = formBytes.Length + imageLength + trailingBytes.Length; 
    uploadRequest.ContentLength = contentLength; 

    uploadRequest.AllowWriteStreamBuffering = false; 
    Stream strm_out = uploadRequest.GetRequestStream(); 

    strm_out.Write(formBytes, 0, formBytes.Length); 

    byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)imageLength))]; 
    int bytesRead = 0; 
    int bytesTotal = 0; 
    imageMemoryStream.Seek(0, SeekOrigin.Begin); 
    while ((bytesRead = imageMemoryStream.Read(buffer, 0, buffer.Length)) != 0) 
    { 
     strm_out.Write(buffer, 0, bytesRead); bytesTotal += bytesRead; 
     gui.OnUploadProgress(this, (int)(bytesTotal * 100/imageLength)); 
    } 

    strm_out.Write(trailingBytes, 0, trailingBytes.Length); 

    strm_out.Close(); 

    HttpWebResponse wresp = uploadRequest.GetResponse() as HttpWebResponse; 
} 
+0

ありがとう@fltz。あなたのサンプル(スニペットの範囲外で宣言されているヴァールのいくつか)を適用することによって、それが機能するように管理されています。 –

+0

アプリケーションが壁に画像を投稿するのか、それともアプリケーションのアルバムにアップロードするだけですか?私のテストでは壁/餌にアップロードされた画像が見えませんでした。 – fltz

+1

私はまだそれを知りませんでした。これまでは、アプリケーションの既定のアルバムが作成されたときに壁にしか表示されません。しかし、[この投稿]によると(http://www.raywenderlich.com/1626/how-to-post-to-a-users-wall-upload-photos-and-add-a-like-button-from-あなたのiPhoneアプリ)それは可能でなければなりません。 –

1

バイト配列を使用して、マルチパート/フォームデータを自分で作成する必要があります。 とにかく私はすでにこれをしています。 Facebook Graph Toolkitはhttp://computerbeacon.net/でチェックできます。私は数日後にバージョン0.8にアップデートします。これには、この「Facebookに写真を投稿する」機能やその他の新機能やアップデートが含まれます。

+0

おかげ - スピンのためにそれを取って楽しみにしています。 –

+0

このサイトにはアクセスできません – zchpit

3

。バイト配列や画像のファイルパスを渡します。既存のアルバムにアップロードする場合は、アルバムIDを渡します。

public string UploadPhoto(string album_id, string message, string filename, Byte[] bytes, string Token) 
{ 
    // Create Boundary 
    string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); 

    // Create Path 
    string Path = @"https://graph.facebook.com/"; 
    if (!String.IsNullOrEmpty(album_id)) 
    { 
     Path += album_id + "/"; 
    } 
    Path += "photos"; 

    // Create HttpWebRequest 
    HttpWebRequest uploadRequest; 
    uploadRequest = (HttpWebRequest)HttpWebRequest.Create(Path); 
    uploadRequest.ServicePoint.Expect100Continue = false; 
    uploadRequest.Method = "POST"; 
    uploadRequest.UserAgent = "Mozilla/4.0 (compatible; Windows NT)"; 
    uploadRequest.ContentType = "multipart/form-data; boundary=" + boundary; 
    uploadRequest.KeepAlive = false; 

    // New String Builder 
    StringBuilder sb = new StringBuilder(); 

    // Add Form Data 
    string formdataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n"; 

    // Access Token 
    sb.AppendFormat(formdataTemplate, boundary, "access_token", HttpContext.Current.Server.UrlEncode(Token)); 

    // Message 
    sb.AppendFormat(formdataTemplate, boundary, "message", message); 

    // Header 
    string headerTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n"; 
    sb.AppendFormat(headerTemplate, boundary, "source", filename, @"application/octet-stream"); 

    // File 
    string formString = sb.ToString(); 
    byte[] formBytes = Encoding.UTF8.GetBytes(formString); 
    byte[] trailingBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); 
    byte[] image; 
    if (bytes == null) 
    { 
     image = File.ReadAllBytes(HttpContext.Current.Server.MapPath(filename)); 
    } 
    else 
    { 
     image = bytes; 
    } 

    // Memory Stream 
    MemoryStream imageMemoryStream = new MemoryStream(); 
    imageMemoryStream.Write(image, 0, image.Length); 

    // Set Content Length 
    long imageLength = imageMemoryStream.Length; 
    long contentLength = formBytes.Length + imageLength + trailingBytes.Length; 
    uploadRequest.ContentLength = contentLength; 

    // Get Request Stream 
    uploadRequest.AllowWriteStreamBuffering = false; 
    Stream strm_out = uploadRequest.GetRequestStream(); 

    // Write to Stream 
    strm_out.Write(formBytes, 0, formBytes.Length); 
    byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)imageLength))]; 
    int bytesRead = 0; 
    int bytesTotal = 0; 
    imageMemoryStream.Seek(0, SeekOrigin.Begin); 
    while ((bytesRead = imageMemoryStream.Read(buffer, 0, buffer.Length)) != 0) 
    { 
     strm_out.Write(buffer, 0, bytesRead); bytesTotal += bytesRead; 
    } 
    strm_out.Write(trailingBytes, 0, trailingBytes.Length); 

    // Close Stream 
    strm_out.Close(); 

    // Get Web Response 
    HttpWebResponse response = uploadRequest.GetResponse() as HttpWebResponse; 

    // Create Stream Reader 
    StreamReader reader = new StreamReader(response.GetResponseStream()); 

    // Return 
    return reader.ReadToEnd(); 
} 
1

IでしたRestSharpを使用して画像を投稿するBLE:

// url example: https://graph.facebook.com/you/photos?access_token=YOUR_TOKEN 
request.AddFile("source", imageAsByteArray, openFileDialog1.SafeFileName, getMimeType(Path.GetExtension(openFileDialog1.FileName))); 
request.addParameter("message", "your photos text here"); 

User APIまたはPage APIを投稿写真を

How to convert Image to Byte Array

注:MIMEタイプとFacebookがそれを把握するために十分にスマートだったので、私は空の文字列を渡しました。 。

0

たぶん便利

 [TestMethod] 
     [DeploymentItem(@".\resources\velas_navidad.gif", @".\")] 
     public void Post_to_photos() 
     { 
      var ImagePath = "velas_navidad.gif"; 
      Assert.IsTrue(File.Exists(ImagePath)); 

      var client = new FacebookClient(AccessToken); 
      dynamic parameters = new ExpandoObject(); 

      parameters.message = "Picture_Caption"; 
      parameters.subject = "test 7979"; 
      parameters.source = new FacebookMediaObject 
{ 
    ContentType = "image/gif", 
    FileName = Path.GetFileName(ImagePath) 
}.SetValue(File.ReadAllBytes(ImagePath)); 

      //// Post the image/picture to User wall 
      dynamic result = client.Post("me/photos", parameters); 
      //// Post the image/picture to the Page's Wall Photo album 
      //fb.Post("/368396933231381/", parameters); //368396933231381 is Album id for that page. 

      Thread.Sleep(15000); 
      client.Delete(result.id); 
     } 

参考: Making Requests

関連する問題