Http post method hanging before getting response using c# [duplicate] - c#

Failed to get response for large file HTTP put create file using c#
I am using file watcher service service monitor, when user created file or folder we are uploading to cloud
if file size more than 512 MB it is taking too much time to get the response
here I am confusing here the issue with my code or server
and reason for this error
if any changes on my code suggest me.
{
var fileFolderObj1 = new FileFolder();
var postURL = apiBaseUri + "/filefolder/create/file/user/" + userId; // +"?type=file";
code = HttpStatusCode.OK;
HttpWebResponse response = null;
FileInfo f = new FileInfo(filePath);
long filesizeF = f.Length;
try
{
string selectedFile = null;
selectedFile = filePath;
var fi = System.IO.Path.GetFileName(filePath);
////commented for some reason
var postParameters = new Dictionary<string, object>();
postParameters.Add("file", new FileParameter(filePath, ""));
postParameters.Add("parentId", parentId);
postParameters.Add("newName", fi);
postParameters.Add("cloudId", cloudId);
postParameters.Add("isSecure", isSecure);
//postParameters.Add("fileSize", fi.Length);
postParameters.Add("fileSize", filesizeF);
var userAgent = "Desktop";
var formDataBoundary = "----WebKitFormBoundary" + DateTime.Now.Ticks.ToString("x");
var uri = new Uri(postURL);
var createFileRequest = WebRequest.Create(uri) as HttpWebRequest;
this.SetBasicAuthHeader(createFileRequest, userId, password);
createFileRequest.ContentType = "multipart/form-data";
createFileRequest.Method = "PUT";
createFileRequest.Timeout = System.Threading.Timeout.Infinite;
createFileRequest.KeepAlive = false;/*true;*/
createFileRequest.UserAgent = userAgent;
createFileRequest.CookieContainer = new CookieContainer();
try
{
using (var requestStream = createFileRequest.GetRequestStream())
{
}
using (response = (HttpWebResponse)createFileRequest.GetResponse())
{
StreamReader(response.GetResponseStream()).ReadToEnd();
fileFolderObj1 = JsonConvert.DeserializeObject<FileFolder>(reslut);
}
}
catch (Exception exc)
{
if (response != null)
{
code = response.StatusCode;
}
}
}
catch (Exception exc)
{
}
}
}
private static readonly Encoding encoding = Encoding.UTF8;
private void WriteMultipartFormData(Dictionary<string, object> postParameters, string boundary, Stream requestStream, ILogService logService = null)
{
var needsCLRF = false;
foreach (var param in postParameters)
{
// Skip it on the first parameter, add it to subsequent parameters.
if (needsCLRF)
{
requestStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));
}
needsCLRF = true;
if (param.Value is FileParameter)
{
var fileToUpload = (FileParameter)param.Value;
// Add just the first part of this param, since we will write the file data directly to the Stream
var header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",
boundary,
param.Key,
fileToUpload.FileName ?? param.Key,
fileToUpload.ContentType ?? "application/octet-stream");
requestStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header));
// Write the file data directly to the Stream, rather than serializing it to a string.
FileStream fileStream = new FileStream(fileToUpload.FileName, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0,buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
logService.Debug("WRITEMULTIPART FORM DATA Bufferlent Running :{0}", bytesRead);
}
fileStream.Close();
}
else
{
var postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
boundary,
param.Key,
param.Value);
requestStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
}
}
// Add the end of the request. Start with a newline
var footer = "\r\n--" + boundary + "--\r\n";
requestStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));
}
}

Related

How Decompress Gzipped Http Get Response in c#

Want to Decompress a Response which is GZipped Getting from an API.Tried the Below Code ,It Always return Like:-
\u001f�\b\0\0\0\0\0\0\0�Y]o........
My code is:
private string GetResponse(string sData, string sUrl)
{
try
{
string script = null;
try
{
string urlStr = #"" + sUrl + "?param=" + sData;
Uri url = new Uri(urlStr, UriKind.Absolute);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
script = reader.ReadToEnd();
}
}
catch (System.Net.Sockets.SocketException)
{
// The remote site is currently down. Try again next time.
}
catch (UriFormatException)
{
// Only valid absolute URLs are accepted
}
return script;
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
I Found the Above Code from many References for Automatic Decompression.But Eventually,it doesn't Work for me.So as to Unzip the zipped Data I tried the Below Function,
private string DecompressGZIP(string compressedText)
{
byte[] gZipBuffer = Convert.FromBase64String(compressedText);
using (var memoryStream = new MemoryStream())
{
int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);
var buffer = new byte[dataLength];
memoryStream.Position = 0;
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
gZipStream.Read(buffer, 0, buffer.Length);
}
return Encoding.UTF8.GetString(buffer);
}
}
But,it also Failed in the First Line of code itself Because of the Following Exception:
System.FormatException: 'The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters. '
As i am a Beginner,Hope You guys will Guide Me .....Thanks in advance....
This is the essential bit which will take care of decoding the gzipped stream:
var clientHandler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate };
var client = new HttpClient(clientHandler);
Just Change My Function as Follows,Which is Perfectly Working For me:
private JObject PostingToPKFAndDecompress(string sData, string sUrl)
{
var jOBj = new JObject();
try
{
try
{
string urlStr = #"" + sUrl + "?param=" + sData;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlStr);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
var t = ReadFully(resStream);
var y = Decompress(t);
using (var ms = new MemoryStream(y))
using (var streamReader = new StreamReader(ms))
using (var jsonReader = new JsonTextReader(streamReader))
{
jOBj = (JObject)JToken.ReadFrom(jsonReader);
}
}
catch (System.Net.Sockets.SocketException)
{
// The remote site is currently down. Try again next time.
}
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
return jOBj;
}
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
public static byte[] Decompress(byte[] data)
{
using (var compressedStream = new MemoryStream(data))
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{
zipStream.CopyTo(resultStream);
return resultStream.ToArray();
}
}

Upload Excel file to web server

I was trying to upload a file to a web server through UWP c# using filestream but it always gives me an error i.e 405 method not allowed when I try to upload on http://example.com/httpdocs/content. Even for testing purpose I tried uploading on my localhost but still no luck.
Any Help?
Code :
public async Task<bool> Upload(StorageFile fileName)
{
HttpMultipartFormDataContent form = new HttpMultipartFormDataContent();
cts = new CancellationTokenSource();
using (IInputStream fileStream = await fileName.OpenSequentialReadAsync())
{
HttpStreamContent content = new HttpStreamContent(fileStream);
form.Add(content, "premier", fileName.Name);
using (HttpClient client = new HttpClient())
{
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri("http://example.com/httpdocs/content")))
{
request.Content = form;
request.Headers.TryAppendWithoutValidation("Content-Type", "application/x-www-form-urlencoded");
HttpResponseMessage response = await client.SendRequestAsync(request).AsTask(cts.Token);
var result = response.Content.ReadAsStringAsync().GetResults();
}
}
}
return true;
}
Hye, after trying much I found this code and it works perfectly. With a little correction that the request will be now sent to an aspx page i.e. http://example.com/abc.aspx. If you wanna send high mb's of excel file data then just change 4096 in Math.Min(4096, (int)fileStream.Length) accordingly
Client Side Code-
public static async Task<string> UploadFileEx(string uploadfile, string
url, string fileFormName, string contenttype, NameValueCollection
querystring, CookieContainer cookies)
{
try
{
if ((fileFormName == null) ||
(fileFormName.Length == 0))
{
fileFormName = "file";
}
if ((contenttype == null) ||
(contenttype.Length == 0))
{
contenttype = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
}
string postdata;
postdata = "?";
if (querystring != null)
{
foreach (string key in querystring.Keys)
{
postdata += key + "=" + querystring.Get(key) + "&";
}
}
Uri uri = new Uri(url + postdata);
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);
webrequest.CookieContainer = cookies;
webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
webrequest.Method = "POST";
// Build up the post message header
StringBuilder sb = new StringBuilder();
sb.Append("--");
sb.Append(boundary);
sb.Append("\r\n");
sb.Append("Content-Disposition: form-data; name=\"");
sb.Append(fileFormName);
sb.Append("\"; filename=\"");
var sd = sb.Append(Path.GetFileName(uploadfile));
sb.Append("\"");
sb.Append("\r\n");
sb.Append("Content-Type: ");
sb.Append(contenttype);
sb.Append("\r\n");
sb.Append("\r\n");
string postHeader = sb.ToString();
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
// Build the trailing boundary string as a byte array
// ensuring the boundary appears on a line by itself
byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
FileStream fileStream = new FileStream(uploadfile, FileMode.Open, FileAccess.Read);
long length = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length;
// webrequest.ContentLength = length;
webrequest.Headers[HttpRequestHeader.ContentLength] = length.ToString();
//Stream requestStream = webrequest.GetRequestStream();
Stream requestStream = await webrequest.GetRequestStreamAsync();
// Write out our post header
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
// Write out the file contents
byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
// Write out the trailing boundary
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
WebResponse response = await webrequest.GetResponseAsync();
Stream s = response.GetResponseStream();
StreamReader sr = new StreamReader(s);
return sr.ReadToEnd();
}
catch (Exception e)
{
e.ToString();
}
return null;
}

JS: Call API from server side

The following JavaScript code is working fine on old i9 browser but not on the latest one. Now I want to call API from server side as this code is not working due to cross domain cores issue.
var xmlHttpDevice = new XMLHttpRequest();
xmlHttpDevice.open("DEVICEINFO", "http://127.0.0.1:" + PortNumber + "/getDeviceInfo", true);
xmlHttpDevice.onload = function (e) {
if (xmlHttpDevice.readyState === 4) {
if (xmlHttpDevice.status === 200) {
alert(xmlHttpDevice.responseText);
} else {
alert(xmlHttpDevice.statusText);
}
}
};
xmlHttpDevice.onerror = function (e) {
console.error(xmlHttpDevice.statusText);
};
var params = "rdverb=DEVICEINFO&URL=''";
xmlHttpDevice.send(params);
my server side code :
TcpClient socket = new TcpClient();
try
{
// Call EndGetContext to complete the asynchronous operation.
HttpListenerContext context = listener.EndGetContext(result);
HttpListenerRequest request = context.Request;
string strPortNumber = string.Empty;
string strRDVerb = "";
int PortNumberStartRange = 11099;
result.AsyncWaitHandle.WaitOne();
if (context.Request.InputStream != null)
{
var body = new StreamReader(context.Request.InputStream).ReadToEnd();
GetPostedData(ref strPortNumber, ref strRDVerb, body);
}
else
{
strPortNumber = "12345";
strRDVerb = "RDSERVICE";
}
if (strRDVerb != "RDSERVICE" && strRDVerb != "DEVICEINFO")
{
strRDVerb = "CAPTURE";
}
//var body = new StreamReader(context.Request.InputStream).ReadToEnd();
string response = string.Empty;
//Get the stream that will be used to send/receive data
ExecuteRecoveryCode(ref socket, PortNumberStartRange);
NetworkStream ns = socket.GetStream();
//Write the HTTP Header info to the stream
StreamWriter sw = new StreamWriter(ns);
if (strRDVerb == "DEVICEINFO")
{
var message = "rdverb=DEVICEINFO&URL=''";
//var data = System.Text.Encoding.ASCII.GetBytes(message);
sw.Write(message, 0, message.Length);
sw.WriteLine(string.Format(strRDVerb + " /getDeviceInfo HTTP/1.1"));
sw.WriteLine(string.Format("HOST:127.0.0.1:11100"));
}
sw.Flush();
//Save the data that lives in the stream
string packet = string.Empty;
StreamReader sr = new StreamReader(ns);
int count = 0;
string EndString = string.Empty;
GetServiceMethod(strRDVerb, ref count, ref EndString);
for (int i = 0; i < count; i++)
{
packet = sr.ReadLine();
response += packet;
}
HttpListenerResponse resp = context.Response;
//byte[] buffer = System.Text.Encoding.UTF8.GetBytes("<HTML><BODY> " + response + EndString + "</BODY></HTML>");
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(response + EndString);
resp.StatusDescription = response;
resp.ContentLength64 = buffer.Length;
System.IO.Stream output = resp.OutputStream;
resp.StatusCode = (int)HttpStatusCode.OK;
output.Write(buffer, 0, buffer.Length);
output.Close();
resp.Close();
}
catch (Exception ex)
{
//throw ex;
}
finally
{
socket.Close();
listener.BeginGetContext(new AsyncCallback(OnRequestReceive), listener);
}

How to upload file to server with HTTP POST multipart/form-data?

I am developing Windows Phone 8 app. I want to upload SQLite database via PHP web service using HTTP POST request with MIME type multipart/form-data & a string data called "userid=SOME_ID".
I don't want to use 3rd party libs like HttpClient, RestSharp or MyToolkit. I tried the below code but it doesn't upload the file & also doesn't give me any errors. It's working fine in Android, PHP, etc so there's no issue in web service. Below is my given code (for WP8). what's wrong with it?
I've googled and I'm not getting specific for WP8
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(DBNAME);
//Below line gives me file with 0 bytes, why? Should I use
//IsolatedStorageFile instead of StorageFile
//var file = await ApplicationData.Current.LocalFolder.GetFileAsync(DBNAME);
byte[] fileBytes = null;
using (var stream = await file.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (var reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
//var res = await HttpPost(Util.UPLOAD_BACKUP, fileBytes);
HttpPost(fileBytes);
}
private void HttpPost(byte[] file_bytes)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.myserver.com/upload.php");
httpWebRequest.ContentType = "multipart/form-data";
httpWebRequest.Method = "POST";
var asyncResult = httpWebRequest.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, file_bytes); }, httpWebRequest);
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult, byte[] postData)
{
//DON'T KNOW HOW TO PASS "userid=some_user_id"
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
postStream.Write(postData, 0, postData.Length);
postStream.Close();
var asyncResult = request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
}
I also tried to solve my problem in Windows 8 but it's also not working.
public async Task Upload(byte[] fileBytes)
{
using (var client = new HttpClient())
{
using (var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture)))
{
content.Add(new StreamContent(new MemoryStream(fileBytes)));
//Not sure below line is true or not
content.Add(new StringContent("userid=farhanW8"));
using (var message = await client.PostAsync("http://www.myserver.com/upload.php", content))
{
var input = await message.Content.ReadAsStringAsync();
}
}
}
}
Basic implementation using MultipartFormDataContent :-
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(new StringContent(username), "username");
form.Add(new StringContent(useremail), "email");
form.Add(new StringContent(password), "password");
form.Add(new ByteArrayContent(file_bytes, 0, file_bytes.Length), "profile_pic", "hello1.jpg");
HttpResponseMessage response = await httpClient.PostAsync("PostUrl", form);
response.EnsureSuccessStatusCode();
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
Here's my final working code. My web service needed one file (POST parameter name was "file") & a string value (POST parameter name was "userid").
/// <summary>
/// Occurs when upload backup application bar button is clicked. Author : Farhan Ghumra
/// </summary>
private async void btnUploadBackup_Click(object sender, EventArgs e)
{
var dbFile = await ApplicationData.Current.LocalFolder.GetFileAsync(Util.DBNAME);
var fileBytes = await GetBytesAsync(dbFile);
var Params = new Dictionary<string, string> { { "userid", "9" } };
UploadFilesToServer(new Uri(Util.UPLOAD_BACKUP), Params, Path.GetFileName(dbFile.Path), "application/octet-stream", fileBytes);
}
/// <summary>
/// Creates HTTP POST request & uploads database to server. Author : Farhan Ghumra
/// </summary>
private void UploadFilesToServer(Uri uri, Dictionary<string, string> data, string fileName, string fileContentType, byte[] fileData)
{
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest.Method = "POST";
httpWebRequest.BeginGetRequestStream((result) =>
{
try
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (Stream requestStream = request.EndGetRequestStream(result))
{
WriteMultipartForm(requestStream, boundary, data, fileName, fileContentType, fileData);
}
request.BeginGetResponse(a =>
{
try
{
var response = request.EndGetResponse(a);
var responseStream = response.GetResponseStream();
using (var sr = new StreamReader(responseStream))
{
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
{
string responseString = streamReader.ReadToEnd();
//responseString is depend upon your web service.
if (responseString == "Success")
{
MessageBox.Show("Backup stored successfully on server.");
}
else
{
MessageBox.Show("Error occurred while uploading backup on server.");
}
}
}
}
catch (Exception)
{
}
}, null);
}
catch (Exception)
{
}
}, httpWebRequest);
}
/// <summary>
/// Writes multi part HTTP POST request. Author : Farhan Ghumra
/// </summary>
private void WriteMultipartForm(Stream s, string boundary, Dictionary<string, string> data, string fileName, string fileContentType, byte[] fileData)
{
/// The first boundary
byte[] boundarybytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
/// the last boundary.
byte[] trailer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
/// the form data, properly formatted
string formdataTemplate = "Content-Dis-data; name=\"{0}\"\r\n\r\n{1}";
/// the form-data file upload, properly formatted
string fileheaderTemplate = "Content-Dis-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n";
/// Added to track if we need a CRLF or not.
bool bNeedsCRLF = false;
if (data != null)
{
foreach (string key in data.Keys)
{
/// if we need to drop a CRLF, do that.
if (bNeedsCRLF)
WriteToStream(s, "\r\n");
/// Write the boundary.
WriteToStream(s, boundarybytes);
/// Write the key.
WriteToStream(s, string.Format(formdataTemplate, key, data[key]));
bNeedsCRLF = true;
}
}
/// If we don't have keys, we don't need a crlf.
if (bNeedsCRLF)
WriteToStream(s, "\r\n");
WriteToStream(s, boundarybytes);
WriteToStream(s, string.Format(fileheaderTemplate, "file", fileName, fileContentType));
/// Write the file data to the stream.
WriteToStream(s, fileData);
WriteToStream(s, trailer);
}
/// <summary>
/// Writes string to stream. Author : Farhan Ghumra
/// </summary>
private void WriteToStream(Stream s, string txt)
{
byte[] bytes = Encoding.UTF8.GetBytes(txt);
s.Write(bytes, 0, bytes.Length);
}
/// <summary>
/// Writes byte array to stream. Author : Farhan Ghumra
/// </summary>
private void WriteToStream(Stream s, byte[] bytes)
{
s.Write(bytes, 0, bytes.Length);
}
/// <summary>
/// Returns byte array from StorageFile. Author : Farhan Ghumra
/// </summary>
private async Task<byte[]> GetBytesAsync(StorageFile file)
{
byte[] fileBytes = null;
using (var stream = await file.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (var reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
return fileBytes;
}
I am very much thankful to Darin Rousseau for helping me.
This simplistic version also works.
public void UploadMultipart(byte[] file, string filename, string contentType, string url)
{
var webClient = new WebClient();
string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x");
webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
var fileData = webClient.Encoding.GetString(file);
var package = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", boundary, filename, contentType, fileData);
var nfile = webClient.Encoding.GetBytes(package);
byte[] resp = webClient.UploadData(url, "POST", nfile);
}
Add any extra required headers if needed.
I've been playing around a little bit and came up with a simplified, more generic solution:
private static string sendHttpRequest(string url, NameValueCollection values, NameValueCollection files = null)
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
// The first boundary
byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
// The last boundary
byte[] trailer = System.Text.Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
// The first time it itereates, we need to make sure it doesn't put too many new paragraphs down or it completely messes up poor webbrick
byte[] boundaryBytesF = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
// Create the request and set parameters
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Get request stream
Stream requestStream = request.GetRequestStream();
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]));
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
requestStream.Write(formItemBytes, 0, formItemBytes.Length);
}
if (files != null)
{
foreach(string key in files.Keys)
{
if(File.Exists(files[key]))
{
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\nContent-Type: application/octet-stream\r\n\r\n", key, files[key]));
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
requestStream.Write(formItemBytes, 0, formItemBytes.Length);
using (FileStream fileStream = new FileStream(files[key], FileMode.Open, FileAccess.Read))
{
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
// Write file content to stream, byte by byte
requestStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
}
}
}
// Write trailer and close stream
requestStream.Write(trailer, 0, trailer.Length);
requestStream.Close();
using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()))
{
return reader.ReadToEnd();
};
}
You can use it like this:
string fileLocation = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Path.DirectorySeparatorChar + "somefile.jpg";
NameValueCollection values = new NameValueCollection();
NameValueCollection files = new NameValueCollection();
values.Add("firstName", "Alan");
files.Add("profilePicture", fileLocation);
sendHttpRequest("http://example.com/handler.php", values, files);
And in the PHP script you could handle data like this:
echo $_POST['firstName'];
$name = $_POST['firstName'];
$image = $_FILES['profilePicture'];
$ds = DIRECTORY_SEPARATOR;
move_uploaded_file($image['tmp_name'], realpath(dirname(__FILE__)) . $ds . "uploads" . $ds . $image['name']);
You can use this class:
using System.Collections.Specialized;
class Post_File
{
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");
byte[] boundarybytesF = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n"); // the first time it itereates, you need to make sure it doesn't put too many new paragraphs down or it completely messes up poor webbrick.
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
wr.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
var nvc2 = new NameValueCollection();
nvc2.Add("Accepts-Language", "en-us,en;q=0.5");
wr.Headers.Add(nvc2);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
Stream rs = wr.GetRequestStream();
bool firstLoop = true;
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
if (firstLoop)
{
rs.Write(boundarybytesF, 0, boundarybytesF.Length);
firstLoop = false;
}
else
{
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, new FileInfo(file).Name, 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);
}
catch (Exception ex)
{
if (wresp != null)
{
wresp.Close();
wresp = null;
}
}
finally
{
wr = null;
}
}
}
use it:
NameValueCollection nvc = new NameValueCollection();
//nvc.Add("id", "TTR");
nvc.Add("table_name", "uploadfile");
nvc.Add("commit", "uploadfile");
Post_File.HttpUploadFile("http://example/upload_file.php", #"C:\user\yourfile.docx", "uploadfile", "application/vnd.ms-excel", nvc);
example server upload_file.php:
m('File upload '.(#copy($_FILES['uploadfile']['tmp_name'],getcwd().'\\'.'/'.$_FILES['uploadfile']['name']) ? 'success' : 'failed'));
function m($msg) {
echo '<div style="background:#f1f1f1;border:1px solid #ddd;padding:15px;font:14px;text-align:center;font-weight:bold;">';
echo $msg;
echo '</div>';
}
Here is what worked for me while sending the file as mult-form data:
public T HttpPostMultiPartFileStream<T>(string requestURL, string filePath, string fileName)
{
string content = null;
using (MultipartFormDataContent form = new MultipartFormDataContent())
{
StreamContent streamContent;
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
streamContent = new StreamContent(fileStream);
streamContent.Headers.Add("Content-Type", "application/octet-stream");
streamContent.Headers.Add("Content-Disposition", string.Format("form-data; name=\"file\"; filename=\"{0}\"", fileName));
form.Add(streamContent, "file", fileName);
using (HttpClient client = GetAuthenticatedHttpClient())
{
HttpResponseMessage response = client.PostAsync(requestURL, form).GetAwaiter().GetResult();
content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
try
{
return JsonConvert.DeserializeObject<T>(content);
}
catch (Exception ex)
{
// Log the exception
}
return default(T);
}
}
}
}
GetAuthenticatedHttpClient used above can be:
private HttpClient GetAuthenticatedHttpClient()
{
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(<yourBaseURL>));
httpClient.DefaultRequestHeaders.Add("Token, <yourToken>);
return httpClient;
}
I know this is and old thread, but I was fighting with this and I would like to share my solution.
This solution works with HttpClient and MultipartFormDataContent, from System.Net.Http. You can release it with .NET Core 1.0 or higher, or .NET Framework 4.5 or higher.
As a quick summary, it's an asynchronous method that receives as parameters the URL in which you want to perform the POST, a key/value collection for sending strings, and a key/value collection for sending files.
private static async Task<HttpResponseMessage> Post(string url, NameValueCollection strings, NameValueCollection files)
{
var formContent = new MultipartFormDataContent(/* If you need a boundary, you can define it here */);
// Strings
foreach (string key in strings.Keys)
{
string inputName = key;
string content = strings[key];
formContent.Add(new StringContent(content), inputName);
}
// Files
foreach (string key in files.Keys)
{
string inputName = key;
string fullPathToFile = files[key];
FileStream fileStream = File.OpenRead(fullPathToFile);
var streamContent = new StreamContent(fileStream);
var fileContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
formContent.Add(fileContent, inputName, Path.GetFileName(fullPathToFile));
}
var myHttpClient = new HttpClient();
var response = await myHttpClient.PostAsync(url, formContent);
//string stringContent = await response.Content.ReadAsStringAsync(); // If you need to read the content
return response;
}
You can prepare your POST like this (you can add so many strings and files as you need):
string url = #"http://yoursite.com/upload.php"
NameValueCollection strings = new NameValueCollection();
strings.Add("stringInputName1", "The content for input 1");
strings.Add("stringInputNameN", "The content for input N");
NameValueCollection files = new NameValueCollection();
files.Add("fileInputName1", #"FullPathToFile1"); // Path + filename
files.Add("fileInputNameN", #"FullPathToFileN");
And finally, call the method like this:
var result = Post(url, strings, files).GetAwaiter().GetResult();
If you want, you can check your status code, and show the reason as below:
if (result.StatusCode == HttpStatusCode.OK)
{
// Logic if all was OK
}
else
{
// You can show a message like this:
Console.WriteLine(string.Format("Error. StatusCode: {0} | ReasonPhrase: {1}", result.StatusCode, result.ReasonPhrase));
}
And if someone need it, here I let a small example of how to receive store a file with PHP (at the other side of our .Net app):
<?php
if (isset($_FILES['fileInputName1']) && $_FILES['fileInputName1']['error'] === UPLOAD_ERR_OK)
{
$fileTmpPath = $_FILES['fileInputName1']['tmp_name'];
$fileName = $_FILES['fileInputName1']['name'];
move_uploaded_file($fileTmpPath, '/the/final/path/you/want/' . $fileName);
}
I hope you find it useful, I am attentive to your questions.
The below code reads a file, converts it to a byte array and then makes a request to the server.
public void PostImage()
{
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
byte[] imagebytearraystring = ImageFileToByteArray(#"C:\Users\Downloads\icon.png");
form.Add(new ByteArrayContent(imagebytearraystring, 0, imagebytearraystring.Count()), "profile_pic", "hello1.jpg");
HttpResponseMessage response = httpClient.PostAsync("your url", form).Result;
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
}
private byte[] ImageFileToByteArray(string fullFilePath)
{
FileStream fs = File.OpenRead(fullFilePath);
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
fs.Close();
return bytes;
}
hi guys after one day searching on web finally i solve problem with below source code
hope to help you
public UploadResult UploadFile(string fileAddress)
{
HttpClient client = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new StringContent("fileToUpload");
form.Add(content, "fileToUpload");
var stream = new FileStream(fileAddress, FileMode.Open);
content = new StreamContent(stream);
var fileName =
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "name",
FileName = Path.GetFileName(fileAddress),
};
form.Add(content);
HttpResponseMessage response = null;
var url = new Uri("http://192.168.10.236:2000/api/Upload2");
response = (client.PostAsync(url, form)).Result;
}
Here is multipart data post with basic authentication C#
public string UploadFilesToRemoteUrl(string url)
{
try
{
Dictionary<string, object> formFields = new Dictionary<string, object>();
formFields.Add("requestid", "{\"id\":\"idvalue\"}");
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
// basic authentication.
var username = "userid";
var password = "password";
string credidentials = username + ":" + password;
var authorization = Convert.ToBase64String(Encoding.Default.GetBytes(credidentials));
request.Headers["Authorization"] = "Basic " + authorization;
request.Method = "POST";
request.KeepAlive = true;
Stream memStream = new System.IO.MemoryStream();
WriteFormData(formFields, memStream, boundary);
FileInfo fileToUpload = new FileInfo(#"filelocation with name");
string fileFormKey = "file";
if (fileToUpload != null)
{
WritefileToUpload(fileToUpload, memStream, boundary, fileFormKey);
}
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 responseSReam = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseSReam);
return streamReader.ReadToEnd();
}
}
catch (WebException ex)
{
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
using (var streamReader = new StreamReader(response.GetResponseStream()))
return streamReader.ReadToEnd();
}
}
}
// write form id.
public static void WriteFormData(Dictionary<string, object> dictionary, Stream stream, string mimeBoundary)
{
string formdataTemplate = "\r\n--" + mimeBoundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
if (dictionary != null)
{
foreach (string key in dictionary.Keys)
{
string formitem = string.Format(formdataTemplate, key, dictionary[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
stream.Write(formitembytes, 0, formitembytes.Length);
}
}
}
// write file.
public static void WritefileToUpload(FileInfo file, Stream stream, string mimeBoundary, string formkey)
{
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + mimeBoundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + mimeBoundary + "--");
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
stream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, formkey, file.Name);
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
stream.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
{
var buffer = new byte[1024];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
stream.Write(buffer, 0, bytesRead);
}
}
stream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
}
For people searching for 403 forbidden issue while trying to upload in multipart form the below might help as there is a case depending on the server configuration that you will get MULTIPART_STRICT_ERROR "!#eq 0" due to incorrect MultipartFormDataContent headers.
Please note that both imagetag/filename variables include quotations (\")
eg filename="\"myfile.png\"" .
MultipartFormDataContent form = new MultipartFormDataContent();
ByteArrayContent imageContent = new ByteArrayContent(fileBytes, 0, fileBytes.Length);
imageContent.Headers.TryAddWithoutValidation("Content-Disposition", "form-data; name="+imagetag+"; filename="+filename);
imageContent.Headers.TryAddWithoutValidation("Content-Type", "image / png");
form.Add(imageContent, imagetag, filename);
I was also wanted to upload stuff to a Server and it was a Spring application i finally discovered that I needed to acctually set an content type for it to interpret it as a file. Just like this:
...
MultipartFormDataContent form = new MultipartFormDataContent();
var fileStream = new FileStream(uniqueTempPathInProject, FileMode.Open);
var streamContent = new StreamContent(fileStream);
streamContent.Headers.ContentType=new MediaTypeHeaderValue("application/zip");
form.Add(streamContent, "file",fileName);
...
I know this is an old post, but after spending an entire afternoon trying, I have to share what worked for me. My solution is for a Xamarin application but the code should still work as long as it is C#:
The issue I had is that I wanted to use the same end-point and payload as my Angular app. (Code Below).
public class ApiService<T> where T : class
{
private string _webServiceUrl = Settings.WebServiceUrl;
private HttpClient httpClient;
public ApiService(string path = null)
{
_webServiceUrl = $"{_webServiceUrl}{path}/";
httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(_webServiceUrl);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Settings.Token);
}
private void HandleException(Exception ex, string url = "")
{
Settings.TotalHttpRequests -= 1;
Crashes.TrackError(ex, new Dictionary<string, string>{ { "URL", url }, });
MessagingCenter.Send<Page, string>(new Page(), "Exception", ex.Message);
}
public async Task<T> PostFormDataAsync(string url, string filePath, T t)
{
using (var form = new MultipartFormDataContent())
{
using (var fs = File.OpenRead(filePath))
{
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
fs.Close();
var json = JsonConvert.SerializeObject(t);
var data = new StringContent(json);
form.Add(new ByteArrayContent(bytes, 0, bytes.Length), "file", fs.Name);
form.Add(data, "data");
Settings.TotalHttpRequests += 1;
var result = await httpClient.PostAsync(url, form);
Settings.TotalHttpRequests -= 1;
if (result.IsSuccessStatusCode)
{
var content = await result.Content.ReadAsStringAsync();
var item = JsonConvert.DeserializeObject<T>(content);
return item;
}
else
{
await RaiseErrorAsync(result);
return default(T);
}
}
}
}
private async Task RaiseErrorAsync(HttpResponseMessage result)
{
var message = await result.Content.ReadAsStringAsync();
MessagingCenter.Send<Page, string>(new Page(), "Error", message);
}
}
I have included some code for the benefit of other Xamarin Developers.
My API endpoint is as follows:
[DisableRequestSizeLimit]
[Consumes("multipart/form-data")]
[HttpPost]
public async Task<ActionResult> Post()
{
try
{
var data = (Request.Form["data"]).ToString();
var myObject = JsonConvert.DeserializeObject<MyClass>(data);
var file = Request.Form.Files[0];
myObject = await _service.AddAsync(myObject, file);
var result = _mapper.Map<MyClassDto>(myObject);
return Ok(result);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
From this, I get my file as an IFormFile instance. I am also able to deserialize the object I sent as t of type T.
The ApiService can be modified to implement IApiService so that you can benefit from Dependency Service (in Xamarin).
On the Angular side, this is what I have on the component:
onSubmit() {
this.submitted = true;
if (this.form.invalid) {return;}
if (this.fileToUpload == null) {
Swal.fire('File', 'Please attach the file', 'error');
return;
}
const formData = new FormData();
formData.append('file', this.fileToUpload, this.fileToUpload.name);
formData.append('data', JSON.stringify(this.form.value));
this.service.postEndpoint('', formData).subscribe((data) => {
//Do something here
});
}
For the service:
import { ApiService } from '../api.service';
#Injectable({
providedIn: 'root'
})
export class MyService extends ApiService<MyClass>{
constructor(protected httpClient: HttpClient) {
super(httpClient, 'MyApiController');
}
}
The ApiService:
const httpOptions = {
headers : new HttpHeaders({
Authorization: 'Bearer ' + localStorage.getItem('token')
})
};
export abstract class ApiService<T> {
basePath = environment.apiPath;
apiURL = `${this.basePath}api/`;
constructor(protected httpClient: HttpClient, protected actionUrl: string) { }
public postEndpoint(endPoint: string, model: any): Observable<any> {
return this.httpClient.post(this.apiURL + `${this.actionUrl}/${endPoint}`, model, httpOptions);
}
}
I hope this saves someone some time! Happy coding!
It work for window phone 8.1. You can try this.
Dictionary<string, object> _headerContents = new Dictionary<string, object>();
const String _lineEnd = "\r\n";
const String _twoHyphens = "--";
const String _boundary = "*****";
private async void UploadFile_OnTap(object sender, System.Windows.Input.GestureEventArgs e)
{
Uri serverUri = new Uri("http:www.myserver.com/Mp4UploadHandler", UriKind.Absolute);
string fileContentType = "multipart/form-data";
byte[] _boundarybytes = Encoding.UTF8.GetBytes(_twoHyphens + _boundary + _lineEnd);
byte[] _trailerbytes = Encoding.UTF8.GetBytes(_twoHyphens + _boundary + _twoHyphens + _lineEnd);
Dictionary<string, object> _headerContents = new Dictionary<string, object>();
SetEndHeaders(); // to add some extra parameter if you need
httpWebRequest = (HttpWebRequest)WebRequest.Create(serverUri);
httpWebRequest.ContentType = fileContentType + "; boundary=" + _boundary;
httpWebRequest.Method = "POST";
httpWebRequest.AllowWriteStreamBuffering = false; // get response after upload header part
var fileName = Path.GetFileName(MediaStorageFile.Path);
Stream fStream = (await MediaStorageFile.OpenAsync(Windows.Storage.FileAccessMode.Read)).AsStream(); //MediaStorageFile is a storage file from where you want to upload the file of your device
string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"" + _lineEnd + _lineEnd + "{1}" + _lineEnd;
long httpLength = 0;
foreach (var headerContent in _headerContents) // get the length of upload strem
httpLength += _boundarybytes.Length + Encoding.UTF8.GetBytes(string.Format(fileheaderTemplate, headerContent.Key, headerContent.Value)).Length;
httpLength += _boundarybytes.Length + Encoding.UTF8.GetBytes("Content-Disposition: form-data; name=\"uploadedFile\";filename=\"" + fileName + "\"" + _lineEnd).Length
+ Encoding.UTF8.GetBytes(_lineEnd).Length * 2 + _trailerbytes.Length;
httpWebRequest.ContentLength = httpLength + fStream.Length; // wait until you upload your total stream
httpWebRequest.BeginGetRequestStream((result) =>
{
try
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (Stream stream = request.EndGetRequestStream(result))
{
foreach (var headerContent in _headerContents)
{
WriteToStream(stream, _boundarybytes);
WriteToStream(stream, string.Format(fileheaderTemplate, headerContent.Key, headerContent.Value));
}
WriteToStream(stream, _boundarybytes);
WriteToStream(stream, "Content-Disposition: form-data; name=\"uploadedFile\";filename=\"" + fileName + "\"" + _lineEnd);
WriteToStream(stream, _lineEnd);
int bytesRead = 0;
byte[] buffer = new byte[2048]; //upload 2K each time
while ((bytesRead = fStream.Read(buffer, 0, buffer.Length)) != 0)
{
stream.Write(buffer, 0, bytesRead);
Array.Clear(buffer, 0, 2048); // Clear the array.
}
WriteToStream(stream, _lineEnd);
WriteToStream(stream, _trailerbytes);
fStream.Close();
}
request.BeginGetResponse(a =>
{ //get response here
try
{
var response = request.EndGetResponse(a);
using (Stream streamResponse = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
{
streamResponse.CopyTo(memoryStream);
responseBytes = memoryStream.ToArray(); // here I get byte response from server. you can change depends on server response
}
if (responseBytes.Length > 0 && responseBytes[0] == 1)
MessageBox.Show("Uploading Completed");
else
MessageBox.Show("Uploading failed, please try again.");
}
catch (Exception ex)
{}
}, null);
}
catch (Exception ex)
{
fStream.Close();
}
}, httpWebRequest);
}
private static void WriteToStream(Stream s, string txt)
{
byte[] bytes = Encoding.UTF8.GetBytes(txt);
s.Write(bytes, 0, bytes.Length);
}
private static void WriteToStream(Stream s, byte[] bytes)
{
s.Write(bytes, 0, bytes.Length);
}
private void SetEndHeaders()
{
_headerContents.Add("sId", LocalData.currentUser.SessionId);
_headerContents.Add("uId", LocalData.currentUser.UserIdentity);
_headerContents.Add("authServer", LocalData.currentUser.AuthServerIP);
_headerContents.Add("comPort", LocalData.currentUser.ComPort);
}
Top to #loop answer.
We got below error for Asp.Net MVC,
Unable to connect to the remote server
Fix:
After adding the below code in Web.Confing issue has been resolved for us
<system.net>
<defaultProxy useDefaultCredentials="true" >
</defaultProxy>
</system.net>
Base on #Wolf5 's answer This works for me
var client = new WebClient();
client.Encoding = Encoding.UTF8;
var boundary = $"--------------------------{DateTime.Now.Ticks:x}";
client.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
client.Headers.Add("Cookie", cookie);
var start = $"--{boundary}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{Path.GetFileName(fileName)}\"\r\nContent-Type: image/jpeg\r\n\r\n";
var end = $"\r\n--{boundary}--\r\n";
var lst = new List<byte>();
lst.AddRange(client.Encoding.GetBytes(start));
lst.AddRange(File.ReadAllBytes(fileName));
lst.AddRange(client.Encoding.GetBytes(end));
var resp = client.UploadData($"{ApiUrl}/api/upload/image", "POST", lst.ToArray());

httpmultipart request for this webservice getdata code in c# with android

HI i have a webservice IIS with this code:
// Implements multipart/form-data POST in C# http://www.ietf.org/rfc/rfc2388.txt
// http://www.briangrinstead.com/blog/multipart-form-post-in-c
public static class FormUpload
{
private static readonly Encoding encoding = Encoding.UTF8;
public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
{
string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
string contentType = "multipart/form-data; boundary=" + formDataBoundary;
byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);
return PostForm(postUrl, userAgent, contentType, formData);
}
private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
{
HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
if (request == null)
{
throw new NullReferenceException("request is not a http request");
}
// Set up the request properties.
request.Method = "POST";
request.ContentType = contentType;
request.UserAgent = userAgent;
request.CookieContainer = new CookieContainer();
request.ContentLength = formData.Length;
// You could add authentication here as well if needed:
// request.PreAuthenticate = true;
// request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
// request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes("username" + ":" + "password")));
// Send the form data to the request.
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(formData, 0, formData.Length);
requestStream.Close();
}
return request.GetResponse() as HttpWebResponse;
}
private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
{
Stream formDataStream = new System.IO.MemoryStream();
bool needsCLRF = false;
foreach (var param in postParameters)
{
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
// Skip it on the first parameter, add it to subsequent parameters.
if (needsCLRF)
formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));
needsCLRF = true;
if (param.Value is FileParameter)
{
FileParameter fileToUpload = (FileParameter)param.Value;
// Add just the first part of this param, since we will write the file data directly to the Stream
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
boundary,
param.Key,
fileToUpload.FileName ?? param.Key,
fileToUpload.ContentType ?? "application/octet-stream");
formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header));
// Write the file data directly to the Stream, rather than serializing it to a string.
formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
}
else
{
string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
boundary,
param.Key,
param.Value);
formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
}
}
// Add the end of the request. Start with a newline
string footer = "\r\n--" + boundary + "--\r\n";
formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));
// Dump the Stream into a byte[]
formDataStream.Position = 0;
byte[] formData = new byte[formDataStream.Length];
formDataStream.Read(formData, 0, formData.Length);
formDataStream.Close();
return formData;
}
public class FileParameter
{
public byte[] File { get; set; }
public string FileName { get; set; }
public string ContentType { get; set; }
public FileParameter(byte[] file) : this(file, null) { }
public FileParameter(byte[] file, string filename) : this(file, filename, null) { }
public FileParameter(byte[] file, string filename, string contenttype)
{
File = file;
FileName = filename;
ContentType = contenttype;
}
}
}
Obtain from here: Multipart forms from C# client
But now, in mi android aplicattion i have this:
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 300000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 300000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpPost postRequest = new HttpPost("http://172.21.1.87:9999/Service1.svc");
ByteArrayBody bab = new ByteArrayBody(ficheroAEnviar, "prueba.jpg");
MultipartEntity reqEntity = new MultipartEntity();
postRequest.addHeader("Content-Type", " multipart/form-data");
reqEntity.addPart("Dictionary", new FileBody(new File(fileUri.toString(), "application/zip")));
reqEntity.addPart("boundary", new StringBody("envio"));
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
postRequest.getAllHeaders();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
System.out.println("Response: " + s);
}
catch (Exception e) {
// handle exception here
Log.e(e.getClass().getName(), e.getMessage());
}
}
But it return me Bad request 400 error. Can i use the c# code to upload a multipartentity file with android or a need to make any change in some code?
Anyone have a example en c# and android to make this? Is for uppload videos about 10 or 15 MB.
Thanks
dont use multipart entity instead use as here you define the bounderies it is easy
try it
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
DataInputStream inputStream = null;
String pathToOurFile = "/data/file_to_send.mp3";
String urlServer = "http://192.168.1.1/handle_upload.php";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1*1024*1024;
try
{
FileInputStream fileInputStream = new FileInputStream(new File(pathToOurFile) );
URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Enable POST method
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
outputStream = new DataOutputStream( connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""+pathToOurFile +"\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = connection.getResponseCode();
serverResponseMessage = connection.getResponseMessage();
fileInputStream.close();
outputStream.flush();
outputStream.close();
}
catch (Exception ex)
{
//Exception handling
}
courtesy rafel

Categories

Resources