application/form-data in C# application? - c#

I have using below code to upload file into url using C# console application.It doesn't upload file and not return error also.
string[] files = new string []{ "C:/test.csv" };
public static string UploadFilesToRemoteUrl(string url, string[] files, 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;
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}";
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=\"{0}\"; filename=\"{1}\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
memStream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, "uplTheFile", files[i]);
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(files[i], 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);
return reader2.ReadToEnd();
}
}
Upload files with HTTPWebrequest (multipart/form-data)
i have checked this code and it doesn't uploaded file in url i was given and also no error return.

This question has been answered already here:
Upload files with HTTPWebrequest (multipart/form-data)
Also, please note that in your code you are actually sending the string "C:/test.csv" and not the contents of the file! You will need to open a FileStream (https://msdn.microsoft.com/en-us/library/system.io.filestream.aspx) to stream out it's contents. (This is also covered in the answer linked above)

Related

Can't seem to upload file using multipart/form-data in C#

I'm trying to upload an image to Imgur's api https://api.imgur.com/3/upload but return status: 400, Bad request BadReqImg.
I'm convinced the issue is coming from file uploading part, as below, but couldn't find any problem with it.
if (files != null)
{
foreach (string key in files.Keys)
{
string filePath = #"C:\Image\" + files[key];
if (File.Exists(filePath))
{
int bytesRead = 0;
byte[] buffer = new byte[2048];
byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n", key, files[key]));
memStream.Write(boundarybytes, 0, boundarybytes.Length);
memStream.Write(formItemBytes, 0, formItemBytes.Length);
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
// Write file content to stream, byte by byte
memStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
}
}
}
Here's the entire code
string Url = "https://api.imgur.com/3/upload";
string retString = string.Empty;
NameValueCollection values = new NameValueCollection();
NameValueCollection files = new NameValueCollection();
values.Add("name", "testpic");
files.Add("image", file);
try
{
string boundary = "-------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.ContentType = "multipart/form-data; boundary=" +
boundary;
request.Method = "POST";
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 + "--");
#region 2
foreach (string key in values.Keys)
{
// Write item to stream
byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}", key, values[key]));
memStream.Write(boundarybytes, 0, boundarybytes.Length);
memStream.Write(formItemBytes, 0, formItemBytes.Length);
}
if (files != null)
{
foreach (string key in files.Keys)
{
string filePath = #"C:\Image\" + files[key];
if (File.Exists(filePath))
{
int bytesRead = 0;
byte[] buffer = new byte[2048];
byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n", key, files[key]));
memStream.Write(boundarybytes, 0, boundarybytes.Length);
memStream.Write(formItemBytes, 0, formItemBytes.Length);
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
// Write file content to stream, byte by byte
memStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
}
}
}
#endregion
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);
retString = reader2.ReadToEnd();
}
}
catch (Exception ex)
{
}
return retString;

HttpWebRequest, uploading a file

I hope someone can help me out. I have the following code, which is attempting to upload a file to the server using a HTTPWebRequest. I simply can't get it to work, resulting in the generic "HTTP Error 500 Internal server" error.
I have tried different iterations, splitting out the code into separate methods etc, but this is the simplest form of the code. I have searched high and low but cannot spot what I'm doing wrong!
Any help would be appreciated.
public HttpWebResponse SubmitPOSTRequest(string url, Dictionary<string, object> postData = null, string fileName = "")
{
byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + this.FormDataBoundary + "\r\n");
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + this.FormDataBoundary;
wr.Method = "POST";
wr.UserAgent = "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)";
wr.CookieContainer = new CookieContainer();
wr.Timeout = 600000;
using (Stream stream = wr.GetRequestStream())
{
if (postData != null)
{
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
// Loop through for non-file form-data.
foreach (string key in postData.Keys)
{
stream.Write(boundaryBytes, 0, boundaryBytes.Length);
string formitem = string.Format(formdataTemplate, key, postData[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
stream.Write(formitembytes, 0, formitembytes.Length);
}
}
if (!string.IsNullOrWhiteSpace(fileName))
{
stream.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, "File", fileName, GetContentType(fileName));
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
stream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
stream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + this.FormDataBoundary + "--\r\n");
stream.Write(trailer, 0, trailer.Length);;
}
return wr.GetResponse() as HttpWebResponse;
}

Split file in chunks then upload via boundary

I'm trying to upload some files to a server.
My code looks like:
public void HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc, string cookie)
{
try
{
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
SetStatus("Making request");
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.Headers["Cookie"] = cookie;
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}";
SetStatus("Parsing values");
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);
SetStatus("Reading file");
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string header = string.Format(headerTemplate, paramName, file, 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();
SetStatus("Sending request");
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
rs.Write(trailer, 0, trailer.Length);
rs.Close();
HttpWebResponse wresp = null;
wresp = (HttpWebResponse)wr.GetResponse();
if (wresp.StatusCode != HttpStatusCode.OK)
{
throw new Exception("File was not uploaded successfully.");
}
SetStatus("Success");
}
catch
{
statusLabel.ForeColor = Color.Red;
SetStatus("Failure");
}
}
An call it in this way:
void uploader_DoWork2(object sender, DoWorkEventArgs e)
{
NameValueCollection c = new NameValueCollection();
c.Add("chunk", "0");
c.Add("name", Path.GetFileName(filenameBox.Text));
c.Add("chunks", "1");
HttpUploadFile("https://site.com/upload.php", filenameBox.Text, "file", GetContentType(filenameBox.Text), c, loginCookies);
}
The script works fine and files are uploaded if these are < 2MB. If the file is larger than 2MB it return success even if the file was not successfully uploaded. I think the files larger than 2MB should be splited in chunks and then send to server. But I have no idea how to split file then send to server in chunks...

Can I post a file and data to a .net mvc web api controller

I have the following .net web api controller method that supports the posting of files to the server.
public Task<HttpResponseMessage> PostFile()
{
var request = Request;
if (!request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType));
}
var root = HttpContext.Current.Server.MapPath("~/App_Data/Uploads");
var provider = new MultipartFileStreamProvider(root);
var task = request.Content.ReadAsMultipartAsy
nc(provider).ContinueWith(o =>
{
var finfo = new FileInfo(provider.FileData.First().LocalFileName);
var guid = Guid.NewGuid().ToString();
File.Move(finfo.FullName,
Path.Combine(root,
guid + "_" + provider.FileData.First().Headers.ContentDisposition.FileName.Replace("\"", "")));
return new HttpResponseMessage
{
Content = new StringContent("File upload.")
};
});
return task;
}
This works well, however I would like to be able to include some metadata about the file as part of the post. At the moment I am have a different web api method for the metadata like
public HttpResponseMessage PostTAG(TAG tag)
Which takes the information in the tag object and saves it to a data base. It would be much easier for my api clients if they could post the file and metadata together in one request. Is this possible in .net web api.
It is possible, where your WEB API declare a parameter for the TAG data. The problems will be your client who post data to your WEB API. If your client using .NET to post data to your WEB API, .NET WebClient does not support posting file along with data
Hence you will need to use lower level HttpWebRequest such as this one
public string UploadFilesToRemoteUrl(string url, Dictionary<string, string> files, NameValueCollection nvc, string contenttype)
{
string boundary = "----------------------------" +
DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest2 = (HttpWebRequest)GetWebRequest(new Uri(url)); //(HttpWebRequest)WebRequest.Create(url);
SetProxy(httpWebRequest2);
SetUserAgent(httpWebRequest2);
httpWebRequest2.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest2.Timeout = WebRequestTimeout; // 60 second * miliseconds * 60 minutes = 1 hour
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.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}";
if (nvc != null)
{
foreach (string key in nvc.Keys)
{
string formitem = string.Format(formdataTemplate, key, nvc[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n\r\n";
if (string.IsNullOrEmpty(contenttype) == false)
{
headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + contenttype + "\r\n";
}
string[] keys = nvc.AllKeys;
foreach (KeyValuePair<string, string> key in files)
{
//string header = string.Format(headerTemplate, "file" + i, files[i]);
//string header = string.Format(headerTemplate, "uplTheFile", files[i]);
string header = string.Format(headerTemplate, key.Key, key.Value);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(key.Value, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[buffsize];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
int progress = Convert.ToInt32((memStream.Length * 100) / fileStream.Length);
ReportProgress(key.Value, progress);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
if (MonitoredDownload != null) MonitoredDownload.OnComplete(key.Value);
buffer = null;
headerbytes = null;
}
httpWebRequest2.ContentLength = memStream.Length;
Stream requestStream = httpWebRequest2.GetRequestStream();
memStream.Position = 0;
byte[] tempBuffer = new byte[buffsize];
int bytereads = 0;
while ((bytereads = memStream.Read(tempBuffer, 0, tempBuffer.Length)) != 0)
{
requestStream.Write(tempBuffer, 0, bytereads);
}
//memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
memStream.Dispose();
//requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
requestStream.Dispose();
WebResponse webResponse2 = httpWebRequest2.GetResponse();
//SaveCookie(webResponse2, new Uri(url).GetLeftPart(UriPartial.Authority));
Stream stream2 = webResponse2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
string str = reader2.ReadToEnd();
reader2.Close();
reader2.Dispose();
stream2.Close();
stream2.Dispose();
webResponse2.Close();
httpWebRequest2 = null;
webResponse2 = null;
tempBuffer = null;
return str;
}
TO use it, simply call
Dictionary<string,string> dict = new Dictionary<string,string>();
dict.Add("file1","c:\\myfile1.jpg");
NamuValueCollection nvc = new NameValueCollection();
nvc.Add("GPSPosition","somegpsvalue");
nvc.Add("CameraModel","somecameramodel");
UploadFilesToRemoteUrl("http://www.remoteurl.com/upload", dict, metadata, "Content-Type: application/octet-stream\r\n");
The above code excerpt is gotten from WebScraper project at http://www.sorainnosia.com/Projects#WS

Send file+parameters in post request

I'm using this code to send parameters to a webpage and getting correct response from it.
System.Net.WebClient oWeb = new System.Net.WebClient();
oWeb.Proxy = System.Net.WebRequest.DefaultWebProxy;
oWeb.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
oWeb.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
byte[] bytArguments = System.Text.Encoding.ASCII.GetBytes("value1=123&value2=xyz");
byte[] bytRetData = oWeb.UploadData("http://website.com/file.php", "POST", bytArguments);
response = System.Text.Encoding.ASCII.GetString(bytRetData);
But now I want to send a file like (.doc) to it + above parameters(value1, value2), but I don't know how to do that.
Use WebClient.QueryString to pass name/value pairs associated with the request.
NameValueCollection parameters = new NameValueCollection();
parameters.Add("value1", "123");
parameters.Add("value2", "xyz");
oWeb.QueryString = parameters;
var responseBytes = oWeb.UploadFile("http://website.com/file.php", "path to file");
string response = Encoding.ASCII.GetString(responseBytes);
public static void HttpUploadFile(string url, string 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, file, 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);
result = reader2.ReadToEnd();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show("Error occurred while converting file", "Error!");
if (wresp != null)
{
wresp.Close();
wresp = null;
}
}
finally
{
wr = null;
}
}
Copied from SO but can't remember it's link. And this is how it will be used
NameValueCollection nvc = new NameValueCollection();
nvc.Add("parm1", "value1");
nvc.Add("parm2", "value2");
nvc.Add("parm3", "value3");
HttpUploadFile("http://www.example.com/upload.php",#filepath, "file", "text/html", nvc);
Here #filepath is the path of your file you want to upload: c:\file_to_upload.doc
And file is the name of the filed used in php as $_Files['file']

Categories