我使用的是Facebook的Javascript的API来开发,这将需要能够发布一个图像到用户的墙的应用程序。 该应用程序的那部分必须是服务器端的,据我所知道的,因为它需要发布的图像数据的multipart / form-data的。
请注意:这不是简单的版本使用的后,但真正的照片法
http://graph.facebook.com/me/photos
我想我面临两个问题,一个.NET和Facebook的问题:
Facebook的问题:我不肯定是否所有参数应发为多部分/表单数据(包括access_token和消息)。唯一的code比如有使用卷曲UTIL /应用程序。
.NET问题:我从来没有发出从.NET的multipart / form-data的请求,我不知道,如果.NET自动创建的mime-部分,或者如果我有恩code。在一些特殊的方法的参数。
这是一个有点难以调试,因为唯一的错误响应我从图形API得到的是400 - 错误的请求。 下面是code,因为它看起来,当我决定写这个问题(是的,这是一个有点冗长: - )
最终的答案当然会是一个示例代码段从发布.NET中的形象,但我可以退而求次。
字符串的用户名= NULL;
串密码= NULL;
INT超时= 5000;
串requestCharset =UTF-8;
串responseCharset =UTF-8;
字符串参数=;
字符串responseContent =;
字符串finishedUrl =https://graph.facebook.com/me/photos;
参数=access_token =+ facebookAccessToken +&放大器;消息=本+ +是一个+图像;
HttpWebRequest的要求= NULL;
请求=(HttpWebRequest的)WebRequest.Create(finishedUrl);
request.Method =POST;
request.KeepAlive = FALSE;
//应用程序/ x-WWW的形式urlen codeD |的multipart / form-data的
request.ContentType =的multipart / form-data的;
request.Timeout =超时;
request.AllowAutoRedirect = FALSE;
如果(用户名= NULL和放大器;!&安培;!用户名=&放大器;&放大器;密码= NULL和放大器;!&放大器;密码=!)
{
请求preAuthenticate = TRUE。
request.Credentials =新的NetworkCredential(用户名,密码).GetCredential(新的URI(finishedUrl),基础);
}
//写参数请求体
流requestBodyStream = request.GetRequestStream();
编码requestParameterEncoding = Encoding.GetEncoding(requestCharset);
byte []的parametersForBody = requestParameterEncoding.GetBytes(参数);
requestBodyStream.Write(parametersForBody,0,parametersForBody.Length);
/ *
这不会工作
byte []的startParm = requestParameterEncoding.GetBytes(&放大器;源=);
requestBodyStream.Write(startParm,0,startParm.Length);
byte []的fileBytes = File.ReadAllBytes(使用Server.Mappath(图像/ sample.jpg));
requestBodyStream.Write(fileBytes,0,fileBytes.Length);
* /
requestBodyStream.Close();
HttpWebResponse响应=无效;
流receiveStream = NULL;
StreamReader的readStream = NULL;
编码的ResponseEncoding = System.Text.Encoding.GetEncoding(responseCharset);
尝试
{
响应=(HttpWebResponse)request.GetResponse();
receiveStream = response.GetResponseStream();
readStream =新的StreamReader(receiveStream,的ResponseEncoding);
responseContent = readStream.ReadToEnd();
}
最后
{
如果(receiveStream!= NULL)
{
receiveStream.Close();
}
如果(readStream!= NULL)
{
readStream.Close();
}
如果(响应!= NULL)
{
response.Close();
}
}
解决方案
下面是一个如何上传二进制数据的样本。但是,一个上传到/我/照片不会在图像发布到墙上:(图像保存到您的应用程序的专辑。我卡在如何宣布,它在饲料中。还有一种方法是张贴图片到华尔街专辑,由URL = = graph.facebook.com/%wall-album-id%/photos ,但并没有找到任何方法来创建苏哈专辑(上载,当用户创建它通过现场图片)。
{
串边界=---------------------------+ DateTime.Now.Ticks.ToString(×);
uploadRequest =(HttpWebRequest的)WebRequest.Create(@https://graph.facebook.com/me/photos);
uploadRequest.ServicePoint.Expect100Continue = FALSE;
uploadRequest.Method =POST;
uploadRequest.UserAgent =Mozilla的/ 4.0(兼容; Windows NT的);
uploadRequest.ContentType =的multipart / form-data的;边界=+边界;
uploadRequest.KeepAlive = FALSE;
StringBuilder的SB =新的StringBuilder();
字符串formdataTemplate = - {0} \ r \ nContent处置:表格数据;名称= \{1} \\ r \ñ\ r \ N {2} \ r \ N的;
sb.AppendFormat(formdataTemplate,边界,access_token,PercentEn code(facebookAccessToken));
sb.AppendFormat(formdataTemplate,边界,消息,PercentEn code(这是一个图像));
字符串HeaderTemplate中= - {0} \ r \ nContent处置:表格数据;名称= \{1} \文件名= \{2} \\ r \ nContent类型:{3} \ r \ñ\ r \ N的;
sb.AppendFormat(HeaderTemplate中,边界,源,file.png,@应用程序/八位字节流);
字符串formString = sb.ToString();
byte []的formBytes = Encoding.UTF8.GetBytes(formString);
byte []的trailingBytes = Encoding.UTF8.GetBytes(\ r \ N--+边界+ - \ r \ N);
长imageLength = imageMemoryStream.Length;
长CONTENTLENGTH = formBytes.Length + imageLength + trailingBytes.Length;
uploadRequest.ContentLength = CONTENTLENGTH;
uploadRequest.AllowWriteStreamBuffering = FALSE;
流strm_out = uploadRequest.GetRequestStream();
strm_out.Write(formBytes,0,formBytes.Length);
byte []的缓冲区=新的字节[检查((UINT)Math.Min(4096,(INT)imageLength))];
INT读取动作= 0;
INT bytesTotal的= 0;
imageMemoryStream.Seek(0,SeekOrigin.Begin);
而((读取动作= imageMemoryStream.Read(缓冲液,0,buffer.Length))!= 0)
{
strm_out.Write(缓冲液,0,读取动作); bytesTotal的+ =读取动作;
gui.OnUploadProgress(此,(int)的(bytesTotal的* 100 / imageLength));
}
strm_out.Write(trailingBytes,0,trailingBytes.Length);
strm_out.Close();
HttpWebResponse wresp = uploadRequest.GetResponse()作为HttpWebResponse;
}
I'm using the Facebooks Javascript API to develop an application that will need to be able to post an image to a users wall. That part of the app needs to be server-side as far as I can tell, since it needs to post the image data as "multipart/form-data".
Note: It's not the simple version using "post", but the real "photos" method.
http://graph.facebook.com/me/photos
I think I'm facing two problems, a .NET and a Facebook problem:
Facebook problem: I'm not quite sure if all parameters should be send as multipart/form-data (including the access_token and message). The only code example there is uses the cUrl util/application.
.NET problem: I have never issued multipart/form-data requests from .NET , and I'm not sure if .NET automatically creates the mime-parts, or if I have to encode the parameters in some special way.
It's a bit hard to debug, since the only error response I get from the Graph API is "400 - bad request". Below is the code as it looked when I decided to write this question (yes, it's a bit verbose :-)
The ultimate answer would of course be a sample snippet posting an image from .NET, but I can settle for less.
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();
}
}
解决方案
Here is a sample of how to upload binary data. But an uploading to /me/photos won't publish the image into wall :( The image saving into your app's album. I'm stuck on how to announce it in the feed. Yet another way is to post an image into "Wall Album", by URL=="graph.facebook.com/%wall-album-id%/photos". But didn't found any way to create sucha album (user creates it when uploading an image via the site).
{
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;
}