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;
}
Related
Noob question here, i'm trying to send a file with one added string parameter.
My uploader class looks like that:
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);
var result = reader2.ReadToEnd();
}
catch (Exception ex)
{
Program.log.Error(System.Reflection.MethodBase.GetCurrentMethod().Name + " Error occurred while converting file ", ex);
if (wresp != null)
{
wresp.Close();
wresp = null;
}
}
finally
{
wr = null;
}
}
The string parameters are inside the NameValueCollection.
Now how should the other side, the post method, receive it?
*Also, in this cases where i mix a file + string parameters, should the content type be "application/octet-stream"?
Thanks
For your case, you can create a FileUploadViewModel to contain all your properties including IFormFile. Use this as parameter type to your action method. Default model binder should be able to populate everything for you.
Also see if you need a custom model binder - https://learn.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-2.1
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)
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...
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']
I am using HttpWebRequest to upload files to an HttpServlet running on tomcat, if the file name contains non-Latin characters the uploaded file on the server has corrupted characters.
this is my file upload method:
public static void HttpUploadFileEx(string url, string file, string paramName, string contentType, NameValueCollection nvc, WebHeaderCollection collection, NetworkCredential networkCredential)
{
log.Debug(string.Format("Uploading {0} to {1}", file, url));
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.UseDefaultCredentials = false;
wr.Credentials = networkCredential;
wr.Timeout = Timeout.Infinite;
foreach (string s in collection)
{
wr.Headers[s] = collection[s];
}
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, Path.GetFileName(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);
log.Debug(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd()));
}
catch (Exception ex)
{
log.Error("Error uploading file", ex);
if (wresp != null)
{
wresp.Close();
wresp = null;
}
}
}
What do I need to change to support non-Latin file names ?
Solved by changing:
wr.ContentType = "multipart/form-data; boundary=" + boundary;
to
wr.ContentType = "multipart/form-data; charset=UTF-8; boundary=" + boundary;