Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a small C# web application.How can I get the c# code that allows user to send files by HTTP POST.It should be able to send text files,image files,excel, csv, doc (all types of files) without using stream reader and all.
You can try the following code:
public void PostMultipleFiles(string url, string[] files)
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = true;
httpWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes =System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary +"\r\n");
string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";
memStream.Write(boundarybytes, 0, boundarybytes.Length);
for (int i = 0; i < files.Length; i++)
{
string header = string.Format(headerTemplate, "file" + i, files[i]);
//string header = string.Format(headerTemplate, "uplTheFile", files[i]);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(files[i], FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
}
httpWebRequest.ContentLength = memStream.Length;
Stream requestStream = httpWebRequest.GetRequestStream();
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
try
{
WebResponse webResponse = httpWebRequest.GetResponse();
Stream stream = webResponse.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string var = reader.ReadToEnd();
}
catch (Exception ex)
{
response.InnerHtml = ex.Message;
}
httpWebRequest = null;
}
Using .NET 4.5 (or .NET 4.0 by adding the Microsoft.Net.Http package from NuGet) there is an easier way to simulate form requests. Here is an example:
private System.IO.Stream Upload(string actionUrl, string paramString, Stream paramFileStream, byte [] paramFileBytes)
{
HttpContent stringContent = new StringContent(paramString);
HttpContent fileStreamContent = new StreamContent(paramFileStream);
HttpContent bytesContent = new ByteArrayContent(paramFileBytes);
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
formData.Add(stringContent, "param1", "param1");
formData.Add(fileStreamContent, "file1", "file1");
formData.Add(bytesContent, "file2", "file2");
var response = client.PostAsync(actionUrl, formData).Result;
if (!response.IsSuccessStatusCode)
{
return null;
}
return response.Content.ReadAsStreamAsync().Result;
}
}
try this
string fileToUpload = #"c:\user\test.txt";
string url = "http://example.com/upload";
using (var client = new WebClient())
{
byte[] result = client.UploadFile(url, fileToUpload);
string responseAsString = Encoding.Default.GetString(result);
}
Related
I need to make a feedback-form in my .NET application, which sends messages to a Rocket.Chat-Channel (What is Rocket.Chat?).
I am already able to send a textmessage with the api of Rocket.Chat.
I found a documentation, how to send files with an api, but i never had done this before. How can I send the files with my Json?
Someone did that before? Maybe somebody can give me a small example to get this done.
This is the code of my method, which sends the textmessage.
private void SendToRocketChat()
{
var baseAddress = "https://plc.ifm-sw.net/api/v1/chat.sendMessage";
var http = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
http.Method = "POST";
http.ContentType = "application/json";
http.Headers.Add("X-Auth-Token", "4ZLqSyN9IEFIkj6SqIde2a4orHhEdL8S0eGPEFdfS9C");
http.Headers.Add("X-User-Id", "rocket.cat");
string rid = "F24Ydk2kkTXAPWsQ9";
JObject Json = new JObject(new JProperty("message", new JObject(new JProperty("rid", rid), new JProperty("msg", WebUtility.HtmlEncode(FeedbackText)))));
ASCIIEncoding encoding = new ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(Json.ToString());
Stream newStream = http.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
var response = http.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
logger.LogInformation(JsonConvert.DeserializeObject(content).ToString().Trim('{', '}'));
}
And this is what i already tried for the Fileupload. Where is my error?
private void SendFileToRocketChat()
{
var url = "https://example-sw.net/api/v1/rooms.upload/:gdfgfgdkTXAPWsQ9";
var filePath = "Abbildung13.jpg";
var httpClient = (HttpWebRequest)WebRequest.Create(new Uri(url));
httpClient.Method = "POST";
httpClient.Headers.Add("X-Auth-Token", "4ZLqSyN9IEhEdLgfd8S0eGPEFdfS9C");
httpClient.Headers.Add("X-User-Id", "rocket.cat");
httpClient.ContentType = "multipart/form-data";
MultipartFormDataContent form = new MultipartFormDataContent();
FileStream fs = File.OpenRead(filePath);
var streamContent = new StreamContent(fs);
var imageContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
form.Add(imageContent, "file", Path.GetFileName(filePath));
form.Add(imageContent, "msg", "This is a message with a file");
form.Add(imageContent, "description", "Simple text file");
var response = httpClient.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
logger.LogInformation(JsonConvert.DeserializeObject(content).ToString().Trim('{', '}'));
}
After some time i got a code, which is working fine. Maybe it will help someone later.
private void SendFileToRocketChat()
{
var url = "https://exampleurl.net/api/v1/rooms.upload/fsgfadgTXAPWsQ9";
var filePath = "text.zip";
NameValueCollection formFields = null;
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
request.Headers.Add("X-Auth-Token", "4ZLqSyN9IEgfasgfdagsdg8S0eGPEFdfS9C");
request.Headers.Add("X-User-Id", "rocket.bot");
Stream memStream = new System.IO.MemoryStream();
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
string files = filePath;
if (formFields != null)
{
foreach (string key in formFields.Keys)
{
string formitem = string.Format(formdataTemplate, key, formFields[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
}
string headerTemplate = "Content-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\n" + "Content-Type: application/zip\r\n\r\n";
memStream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, "file", files);
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(files, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[1024];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
}
memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
request.ContentLength = memStream.Length;
using (Stream requestStream = request.GetRequestStream())
{
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
}
using (var response = request.GetResponse())
{
Stream stream2 = response.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
string res = reader2.ReadToEnd();
logger.LogInformation(JsonConvert.DeserializeObject(res).ToString().Trim('{', '}'));
}
}
I am using a modified version of the C# API Example to add tasks to an existing Workfront (AtTask) Task. I would also like to upload and download file attachments.
It appears from the documentation that uploading is a two-step process, step 1 upload the file and step 2 attach the uploaded file to the task. I understand somewhat how to do the second step - post a JSON token with the file name, the handle (from the upload), object type (TASK), object ID, and currentVersion. What I don't understand is step 1, the actual uploading of the file.
I am creating a PDF file that needs to be attached to the task. Once the task is completed, a new document will be added that I need to download.
Does anyone have any C# code for performing either the upload or the download?
Here is my code so far:
public JToken DoUpload(string path, string opportunityID, string description, params string[] parameters)
{
List<string> list = parameters.ToList();
if (!path.StartsWith("/"))
{
path = "/" + path;
}
string fullUrl = url + path + ToQueryString(parameters);
string boundary = "------" + DateTime.Now.Ticks.ToString("x");
WebRequest request = HttpWebRequest.CreateDefault(new Uri(fullUrl));
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
using (var requestStream = request.GetRequestStream())
{
using (var writer = new StreamWriter(requestStream))
{
writer.WriteLine(string.Format("Content-Disposition: form-data; name=\"{0}\" filename=\"{1}\"", "uploadedFile", "RFQ" + opportunityID + ".html"));
writer.WriteLine("Content-Type: text/html; charset=UTF-8");
writer.WriteLine();
writer.WriteLine(description);
using (WebResponse response = request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
return ReadResponse(responseStream);
}
}
}
}
}
public static string HttpUploadFile(string url, string filename, byte[] file, string paramName, string contentType, NameValueCollection nvc)
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
Stream rs = wr.GetRequestStream();
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
rs.Write(boundarybytes, 0, boundarybytes.Length);
string formitem = string.Format(formdataTemplate, key, nvc[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
rs.Write(formitembytes, 0, formitembytes.Length);
}
rs.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string header = string.Format(headerTemplate, paramName, filename, contentType);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length);
rs.Write(file, 0, file.Length);
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
rs.Write(trailer, 0, trailer.Length);
rs.Close();
WebResponse wresp = null;
string ret = null;
try
{
wresp = wr.GetResponse();
Stream stream2 = wresp.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
ret = reader2.ReadToEnd();
}
catch (Exception ex)
{
if (wresp != null)
{
wresp.Close();
wresp = null;
}
}
finally
{
wr = null;
}
return ret;
}
JToken ret = HttpUploadFile("/upload", file_name, file_bytes, "uploadedFile", "", new NameValueCollection());
The first step is to get a handel, that is done just like any other api call you do to POST /attask/api/upload, this is where you include the file, it will be uploaded to a temp folder at Workfront(AtTask), Workfront will return the handel, then you do a second step to update the task incldue the handel and the file will be posted to it.
For more reference check out https://developers.attask.com/api-docs/ and https://developers.attask.com/api-docs/code-samples/
I Tries to upload a file using the HTTPWebrequest(multipart/form-data).
So I see a few pages, and wrote the following code :
var boundary = "----------" + DateTime.Now.Ticks.ToString("x");
byte[] boundaryBytes = Encoding.ASCII.GetBytes(boundary);
var template = boundary + "\r\n" +
"Content-Disposition: form-data; name=\"{0}\"" + "\r\n\r\n" +
"{1}\r\n";
// Request Header
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://domain.com/test.php");
req.Method = "POST";
req.KeepAlive = true;
req.ContentType = "multipart/form-data; boundary=" + boundary;
req.CookieContainer = COOKIE;
Stream ms = new MemoryStream();
string formItem;
byte[] formItemBytes;
string fileName = Path.GetFileName(#"C:\Users\Username\Image.jpg");
// POST Data
formItem = string.Format(template, "Filename", fileName);
formItemBytes = Encoding.UTF8.GetBytes(formItem);
ms.Write(formItemBytes, 0, formItemBytes.Length);
formItem = string.Format(template, "Username", "RedPetals");
formItemBytes = Encoding.UTF8.GetBytes(formItem);
ms.Write(formItemBytes, 0, formItemBytes.Length);
var headerTemplate = "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n";
string header = string.Format(headerTemplate, "Image", fileName);
byte[] headerBytes = Encoding.UTF8.GetBytes(header);
ms.Write(boundaryBytes, 0, boundaryBytes.Length);
ms.Write(headerBytes, 0, headerBytes.Length);
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
{
ms.Write(buffer, 0, bytesRead);
}
}
byte[] boundaryEndBytes = Encoding.ASCII.GetBytes(boundary + "--");
ms.Write(boundaryEndBytes, 0, boundaryEndBytes.Length);
req.ContentLength = ms.Length;
ms.Position = 0;
byte[] tempBuffer = new byte[ms.Length];
ms.Read(tempBuffer, 0, tempBuffer.Length);
ms.Close();
using(Stream rs = req.GetRequestStream())
{
rs.Write(tempBuffer, 0, tempBuffer.Length);
}
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
string result = "";
if (response.StatusCode == HttpStatusCode.OK)
{
Stream resStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(resStream, Encoding.UTF8);
result = readStream.ReadToEnd();
Console.Write(result);
resStream.Close();
readStream.Close();
}
But does not pass POST data.. Is there a part I missed?
HttpAnalyzer Post 'Data'(Formdata tab is 'No data to display') :
----------8d1984e7dd49750
Content-Disposition: form-data; name="Filename"
Image.jpg
----------8d1984e7dd49750
Content-Disposition: form-data; name="Username"
RedPetals
----------8d1984e7dd49750
Content-Disposition: form-data; name="img"; filename="Image.jpg"
Content-Type: application/octet-stream
???
----------8d1984e7dd49750--
Response result :
// echo var_dump($_POST); echo var_dump($_FILES);
array(0) { } array(0) { }
Resolved
//var boundary = "----------" + DateTime.Now.Ticks.ToString("x");
var boundary = "--------" + DateTime.Now.Ticks.ToString("x");
// var template = boundary + "\r\n" +
// "Content-Disposition: form-data; name=\"{0}\"" + "\r\n\r\n" +
// "{1}\r\n";
var template = "--" + boundary + "\r\n" +
"Content-Disposition: form-data; name=\"{0}\"" + "\r\n\r\n" +
"{1}\r\n";
Here's my solution when I encountered this issue:
Client:
public async Task UploadImage(byte[] image, string url)
{
Stream stream = new System.IO.MemoryStream(image);
HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream());
Uri resourceAddress = null;
Uri.TryCreate(url.Trim(), UriKind.Absolute, out resourceAddress);
Windows.Web.Http.HttpRequestMessage request = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, resourceAddress);
request.Content = streamContent;
var httpClient = new Windows.Web.Http.HttpClient();
var cts = new CancellationTokenSource();
Windows.Web.Http.HttpResponseMessage response = await httpClient.SendRequestAsync(request).AsTask(cts.Token);
}
Controller:
public async Task<HttpResponseMessage> Post()
{
Stream requestStream = await this.Request.Content.ReadAsStreamAsync();
byte[] byteArray = null;
using (MemoryStream ms = new MemoryStream())
{
await requestStream.CopyToAsync(ms);
byteArray = ms.ToArray();
}
.
.
.
return Request.CreateResponse(HttpStatusCode.OK);
}
I am trying to upload a file to OneDrive using REST but am seeing a 400 bad request error when I try to do so. This is my code:
//Where I call it
//fileLoc being C:\\path\\test.doc
HttpUploadFile("https://apis.live.net/v5.0/folder.xxxxxxxx/files/" + "?" + access_token, #fileLoc, "file", "application/octet-stream");
public static void HttpUploadFile(string url, string file, string paramName, string contentType)
{
log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
log.Debug(string.Format("Uploading {0} to {1}", file, url));
string boundary = "A300x";// "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
Stream rs = wr.GetRequestStream();
rs.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string header = string.Format(headerTemplate, paramName, "TEMPTEST.docx", contentType);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, bytesRead);
}
fileStream.Close();
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
rs.Write(trailer, 0, trailer.Length);
rs.Close();
WebResponse wresp = null;
try
{
wresp = wr.GetResponse();
Stream stream2 = wresp.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
log.Debug(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd()));
MessageBox.Show("Success!");
}
catch (Exception ex)
{
log.Error("Error uploading file", ex);
if (wresp != null)
{
wresp.Close();
wresp = null;
}
MessageBox.Show("There was an error!" + Environment.NewLine + ex.Message);
}
finally
{
wr = null;
}
}
Can anyone see what my problem would be? I initially had my scope not set to be able to write but have corrected that so it is not the issue.
I would guess that content-disposition header is wrong. The spec says the header should look like
Content-Disposition: Attachment; filename=example.html
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;
}
Cleaned up class method using #fitz's code. Pass in a byte array or a file path for the image. Pass in an album id if uploading to an existing album.
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();
}
You have to construct the multipart/form-data yourself using byte arrays.
Anyway I've already done this. You can check out the Facebook Graph Toolkit at http://computerbeacon.net/ . I'll update the toolkit to version 0.8 in a few days, which will include this "post photo to facebook wall" function as well as other new features and updates.
I was able to post pictures using 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");
User API or Page API for posting photos
How to convert Image to Byte Array
Note: I was passing an empty string as the mime type and facebook was smart enough to figure it out.
Maybe useful
[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);
}
Reference:
Making Requests