发布图像从.NET使用图形API的Facebook墙上墙上、图形、图像、NET

2023-09-03 01:00:02 作者:我就是我没第二个我

我使用的是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 =htt​​ps://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();
    }
}
 
如何使用图形API在您的Facebook页面上发布

解决方案

下面是一个如何上传二进制数据的样本。但是,一个上传到/我/照片不会在图像发布到墙上:(图像保存到您的应用程序的专辑。我卡在如何宣布,它在饲料中。还有一种方法是张贴图片到华尔街专辑,由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;
}