我正在使用Facebook的Javascript API来开发一个需要能够将图像发布到用户墙的应用程序。 据我所知,应用程序的那部分需要服务器端,因为它需要将图像数据发布为“multipart / form-data”。
注意:这不是使用“post”的简单版本,而是真正的“照片”方法。
http://graph.facebook.com/me/photos
我认为我面临两个问题,即.NET和Facebook问题:
Facebook问题:我不太确定是否所有参数都应作为multipart / form-data(包括access_token和message)发送。唯一的代码示例是使用cUrl util / application。
.NET问题:我从未从.NET发出多部分/表单数据请求,我不确定.NET是否会自动创建mime-parts,或者我是否需要编码参数以某种特殊的方式。
调试有点困难,因为我从Graph 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();
}
}
答案 0 :(得分:4)
以下是如何上传二进制数据的示例。但上传到/我/照片不会将图像发布到墙上:(图像保存到您应用的相册中。我一直坚持如何在Feed中宣布它。另一种方法是将图像发布到“墙上”相册“,通过网址==” graph.facebook.com/%wall-album-id%/photos “。但是没有找到任何方法来创建sucha相册(用户在上传时创建它图片来自网站)。
{
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;
}
答案 1 :(得分:3)
使用@ fitz的代码清理类方法。传入图像的字节数组或文件路径。如果上传到现有相册,则传入相册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();
}
答案 2 :(得分:1)
您必须使用字节数组自己构造multipart / form-data。 无论如何,我已经做到了这一点。您可以在http://computerbeacon.net/查看Facebook Graph Toolkit。我会在几天内将工具包更新到0.8版,其中包括“post photo to facebook wall”功能以及其他新功能和更新。
答案 3 :(得分:1)
我可以使用RestSharp发布图片:
// 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");
用于发布照片的
How to convert Image to Byte Array
注意:我传递的是一个空字符串作为mime类型,而facebook很聪明,可以解决它。
答案 4 :(得分: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