 |
|
 |
I managed to get it working for post forms.. modified code below..may be of use to others.
Public Function UploadFileEx2(ByVal theReferer As String, ByVal postMethod As String, ByVal uploadfilename As String, ByVal url As String, ByVal fileFormName As String, ByVal contenttype As String, ByVal querystring As System.Collections.Specialized.NameValueCollection, ByVal cookies As CookieContainer) As String
Try
Dim uri As Uri
If (fileFormName Is Nothing) OrElse (fileFormName.Length = 0) Then
fileFormName = "file"
End If
If (contenttype Is Nothing) OrElse (contenttype.Length = 0) Then
contenttype = "application/octet-stream"
End If
Dim postdata As String
postdata = "?"
If Not (querystring Is Nothing) Then
For Each key As String In querystring.Keys
postdata += key + "=" + querystring.Get(key) + "&"
Next
End If
If postMethod = "POST" Then
uri = New Uri(url)
Else
uri = New Uri(url + postdata)
End If
Dim boundary As String = "----------" + DateTime.Now.Ticks.ToString("x")
Dim webrequest As HttpWebRequest
webrequest = HttpWebRequest.Create(uri)
webrequest.CookieContainer = cookies
webrequest.ContentType = "multipart/form-data; boundary=" + boundary
webrequest.Method = postMethod
Dim sb As StringBuilder = New StringBuilder
If postMethod = "POST" Then
For Each key As String In querystring.Keys
sb.Append("--")
sb.Append(boundary)
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("Content-Disposition: form-data; name=""")
sb.Append(key)
sb.Append("""" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append(querystring.Get(key))
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
Next
End If
sb.Append("--")
sb.Append(boundary)
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("Content-Disposition: form-data; name=""")
sb.Append(fileFormName)
sb.Append("""; filename=""")
sb.Append(Path.GetFileName(uploadfilename))
sb.Append("""")
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("Content-Type: ")
sb.Append(contenttype)
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
Dim postHeader As String = sb.ToString
Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(postHeader)
Dim boundaryBytes As Byte() = Encoding.ASCII.GetBytes("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "--" + boundary + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
Dim fileStream As FileStream = New FileStream(uploadfilename, FileMode.Open, FileAccess.Read)
Dim length As Long = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length
webrequest.ContentLength = length
webrequest.Referer = theReferer
Dim requestStream As Stream = webrequest.GetRequestStream
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length)
Dim sendBuffer(Math.Min(4096, fileStream.Length)) As Byte
Dim bytesRead As Integer = 0
'Dim r As New BinaryReader(fileStream)
Do
bytesRead = fileStream.Read(sendBuffer, 0, sendBuffer.Length)
If bytesRead = 0 Then Exit Do
requestStream.Write(sendBuffer, 0, bytesRead)
Loop
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
requestStream.Flush()
requestStream.Close()
Dim responce As WebResponse = webrequest.GetResponse
Dim s As Stream = responce.GetResponseStream
Dim sr As StreamReader = New StreamReader(s)
Dim buf As String = sr.ReadToEnd
Return sr.ReadToEnd
Catch ex As Exception
MsgBox("Error in uploadfileEx:" & ex.ToString)
Return ""
End Try
|
|
|
|
 |
|
 |
The line:
byte[] boundaryBytes =
Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
Should be:
byte[] boundaryBytes =
Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n")
It needs the two extra hyphens at the end otherwise you'll get an error 400 returned from the server.
I hope this helps someone as it nearly drove me insane !
|
|
|
|
 |
|
|
 |
|
 |
I get time-out exception when I try to upload file throught proxy
I've added webrequest.Proxy = new WebProxy(ProxyHost, ProxyPort) but it doesn't help
|
|
|
|
 |
|
 |
when i try this code i have an error withs files greater than 7 MB...
here is this error:
(traduction frome french please forgive my bad english)
System.IO.IOException: unable to write data to the transport connection: and blocking operation had been interrupted by a call of WSACancellBlockingCall
doeas anybody having a clue on how resolving it?
thx
warenbe
|
|
|
|
 |
|
 |
Not sure if you are still looking for this, but we had what I think is your error, the HttpWebRequest has a Timeout property, which defaults to 100000 ms, we upped that and it now seems to be working for larger files.
If anyone else is getting the error: IO.Exception, Cannot close stream until all bytes are written, this is another way this expresses itself.
|
|
|
|
 |
|
 |
Well my error diseapeared and now i'm able to send a file greater than 100MB
but i'm not using your function: i'm using WebClient.UploadFileAsync from the .net framework 2.0
it work fine and do the same thing as yuor function but we don't have full control of what is sent... sorry for my bad english
|
|
|
|
 |
|
|
 |
|
 |
how can asp file recieve my request
sdfsdfsdf
|
|
|
|
 |
|
 |
Is there a way to receive some type of response from the server to see if it was successful or not?
|
|
|
|
 |
|
 |
Is there any way of hooking a progress bar into this function to give the user some idea of how fast the data is being transferred?
|
|
|
|
 |
|
 |
// Write out the file contents
byte[] buffer = new Byte[4096];
int bytesRead = 0;
int totalBytes =0;
while ( (bytesRead = fileStream.Read(buffer, 0, 4096)) != 0 )
{
requestStream.Write(buffer, 0, bytesRead);
totalBytes +=bytesRead;
double percentDone = totalBytes/(double) fileStream.Length;
//update progress here
}
Note: this is not tested or compliled at all so it may crash in one way or another but I think you can get the point.
|
|
|
|
 |
|
 |
It doesn't work because the data appears be transfered only after requestStream.Close()
|
|
|
|
 |
|
 |
my understanding is that ur while condition reads the entire file into through each loop. anyways i wrote something that works for the interested.
ps. (great job on the class im using it a lot)
Stream requestStream = webrequest.GetRequestStream();
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
// Reads all bytes and places it in byte array
byte[] buffer = File.ReadAllBytes(uploadfile);
int bytesRead = 0;
int i = 0; // used to keep track of bytesRead length in buffer
while ((bytesRead = fileStream.ReadByte()) != -1) {
requestStream.WriteByte(buffer[i]);
int percent = Convert.ToInt32((i / (double)fileStream.Length) * 100);
Debug.write("%" + percent.ToString()); // my debug
i++;
}
enjoy!
|
|
|
|
 |
|
 |
Hi,
Ive tryed your code to upload a file but I got the 401.1 error. This error means that I dont have the required credentials, this is strange because I'm working with localhost. I've tryed to upload the file using the browser and it works fine, but from my application I got this error.
Id like to have some help on this, thanks.
please use Antonio.mm.neves@gmail.com
|
|
|
|
 |
|
 |
Thanks for the vb.net version. It was just what i was looking for. I had to make a small change to the code to make it work. I just had to swap 2 lines around while creating the post string. Here's the updated version
------------------------------------------------------------------------
Public Shared Function UploadFile(ByVal uploadfilename As String, ByVal url As String, ByVal fileFormName As String, ByVal contenttype As String, ByVal querystring As System.Collections.Specialized.NameValueCollection, ByVal cookies As CookieContainer) As String
If (fileFormName Is Nothing) OrElse (fileFormName.Length = 0) Then
fileFormName = "file"
End If
If (contenttype Is Nothing) OrElse (contenttype.Length = 0) Then
contenttype = "application/octet-stream"
End If
Dim postdata As String
postdata = "?"
If Not (querystring Is Nothing) Then
For Each key As String In querystring.Keys
postdata += key + "=" + querystring.Get(key) + "&"
Next
End If
Dim uri As Uri = New Uri(url + postdata)
Dim boundary As String = "----------" + DateTime.Now.Ticks.ToString("x")
Dim webrequest As HttpWebRequest = CType(webrequest.Create(uri), HttpWebRequest)
webrequest.CookieContainer = cookies
webrequest.ContentType = "multipart/form-data; boundary=" + boundary
webrequest.Method = "POST"
Dim sb As StringBuilder = New StringBuilder
sb.Append("--")
sb.Append(boundary)
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("Content-Disposition: form-data; name=""")
sb.Append(fileFormName)
sb.Append("""; filename=""")
sb.Append(Path.GetFileName(uploadfilename))
sb.Append("""")
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("Content-Type: ")
sb.Append(contenttype)
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
Dim postHeader As String = sb.ToString
Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(postHeader)
Dim boundaryBytes As Byte() = Encoding.ASCII.GetBytes("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "--" + boundary + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
Dim fileStream As FileStream = New FileStream(uploadfilename, FileMode.Open, FileAccess.Read)
Dim length As Long = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length
webrequest.ContentLength = length
Dim requestStream As Stream = webrequest.GetRequestStream
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length)
Dim sendBuffer(Math.Min(4096, fileStream.Length)) As Byte
Dim bytesRead As Integer = 0
'Dim r As New BinaryReader(fileStream)
Do
bytesRead = fileStream.Read(sendBuffer, 0, sendBuffer.Length)
If bytesRead = 0 Then Exit Do
requestStream.Write(sendBuffer, 0, bytesRead)
Loop
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
requestStream.Flush()
requestStream.Close()
Dim responce As WebResponse = webrequest.GetResponse
Dim s As Stream = responce.GetResponseStream
Dim sr As StreamReader = New StreamReader(s)
Return sr.ReadToEnd
End Function
|
|
|
|
 |
|
 |
Thanks your code. It is very nice.
But, I in my php whenever use move_uploaded_file return false.
Can you upload this code in php?
|
|
|
|
 |
|
 |
Hi, I need to post files to a webserver from pocketpc, but teh .NET CF does not support Cookies, so I just remove references to cookies in you code. Is that correct or do I need to make more changes?
Thank you,
Sergio
|
|
|
|
 |
|
 |
I use the following code successfuly with easyphp 1.8, remove the cookiecontainer because .netCF does no support it. Remember to change the target host. Used the same php script as above. I uploaded 4 files, it does not hang or give any errors.
------------------------ CODE START ------------------------
public void DoTest()
{
NameValueCollection querystring = new NameValueCollection();
querystring["uname"]="uname";
querystring["passwd"]="snake3";
string uploadfile;// set to file to upload
string outdata;
uploadfile = "\\My Documents\\image.jpg";
outdata = UploadFileEx(uploadfile, "http://remotehostIP:80/test.php", "uploadfile", "image/pjpeg", querystring);
MessageBox.Show(outdata);
}
private static string UploadFileEx(string uploadfile, string url,
string fileFormName, string contenttype, NameValueCollection querystring)
{
if(fileFormName == null || fileFormName.Length == 0)
fileFormName = "file";
if(contenttype == null || contenttype.Length == 0)
contenttype = "application/octet-stream";
string postdata;
postdata = "?";
if (querystring != null)
{
foreach(string key in querystring.Keys)
postdata += key+"="+querystring.Get(key)+"&";
}
EscapedUri uri=new EscapedUri(url+postdata);
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);
webrequest.ContentType = "multipart/form-data; boundary="+boundary;
webrequest.Method = "POST";
webrequest.AllowWriteStreamBuffering = false;
// 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=\"");
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;
Stream requestStream=webrequest.GetRequestStream();
// 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 = fileStream.Read(buffer, 0, buffer.Length);
while (bytesRead != 0 )
{
requestStream.Write(buffer, 0, bytesRead);
bytesRead = fileStream.Read(buffer, 0, buffer.Length);
}
fileStream.Close();
// Write out the trailing boundary
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
requestStream.Flush();
requestStream.Close(); //very important
string result="";
WebResponse response=webrequest.GetResponse();
if (webrequest.HaveResponse)
{
Stream s=response.GetResponseStream();
StreamReader sr=new StreamReader(s);
result = sr.ReadToEnd();
sr.Close();
s.Close();
response.Close();
}
buffer = null;
fileStream = null;
uri = null;
return result;
}
------------------------ CODE END ------------------------
|
|
|
|
 |
|
 |
Thanks! A great help. I translated this to vb.net for our project. i will post it here if anyone is interested in it:
Public Shared Function UploadFile(ByVal uploadfilename As String, ByVal url As String, ByVal fileFormName As String, ByVal contenttype As String, ByVal querystring As System.Collections.Specialized.NameValueCollection, ByVal cookies As CookieContainer) As String
Try
If (fileFormName Is Nothing) OrElse (fileFormName.Length = 0) Then
fileFormName = "file"
End If
If (contenttype Is Nothing) OrElse (contenttype.Length = 0) Then
contenttype = "application/octet-stream"
End If
Dim postdata As String
postdata = "?"
If Not (querystring Is Nothing) Then
For Each key As String In querystring.Keys
postdata += key + "=" + querystring.Get(key) + "&"
Next
End If
Dim uri As Uri = New Uri(url + postdata)
Dim boundary As String = "----------" + DateTime.Now.Ticks.ToString("x")
Dim webrequest As HttpWebRequest = CType(webrequest.Create(uri), HttpWebRequest)
webrequest.CookieContainer = cookies
webrequest.ContentType = "multipart/form-data; boundary=" + boundary
webrequest.Method = "POST"
Dim sb As StringBuilder = New StringBuilder
sb.Append(boundary)
sb.Append("--")
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("Content-Disposition: form-data; name=""")
sb.Append(fileFormName)
sb.Append("""; filename=""")
sb.Append(Path.GetFileName(uploadfilename))
sb.Append("""")
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("Content-Type: ")
sb.Append(contenttype)
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
Dim postHeader As String = sb.ToString
Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(postHeader)
Dim boundaryBytes As Byte() = Encoding.ASCII.GetBytes("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "--" + boundary + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
Dim fileStream As FileStream = New FileStream(uploadfilename, FileMode.Open, FileAccess.Read)
Dim length As Long = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length
webrequest.ContentLength = length
Dim requestStream As Stream = webrequest.GetRequestStream
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length)
Dim sendBuffer(Math.Min(4096, fileStream.Length)) As Byte
Dim bytesRead As Integer = 0
'Dim r As New BinaryReader(fileStream)
Do
bytesRead = fileStream.Read(sendBuffer, 0, sendBuffer.Length)
If bytesRead = 0 Then Exit Do
requestStream.Write(sendBuffer, 0, bytesRead)
Loop
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
requestStream.Flush()
requestStream.Close()
Dim responce As WebResponse = webrequest.GetResponse
Dim s As Stream = responce.GetResponseStream
Dim sr As StreamReader = New StreamReader(s)
Return sr.ReadToEnd
Catch Exc As Exception
Debug.WriteLine(ControlChars.Cr + "Exception: " & Exc.Message)
End Try
End Function
|
|
|
|
 |
|
 |
Without setting the HttpWebRequest class property AllowWriteStreamBuffering to false, uploading extremly large files (e. g. 1 GB) causes client (and sometimes serverside) out of memory exceptions.
And don't forget to close all streams.
|
|
|
|
 |
|
 |
I'm quite frustrated because i can't find the error.
I want to upload one file after.
the first one works perfekt but the second file doesn't upload because the program hangs up at the line:
Stream requestStream = ebrequest.GetRequestStream();
no exception,-nothing- it only hangs up.
Does anyone know where the problem is ? after hours of seaching i sill can't locate the problem
thanks
NuRmus
|
|
|
|
 |
|
 |
After writing out the trailing boundary, issue
requestStream.Flush()
requestStream.Close()
in order to finish writing. This is probably the problem.
Also, I believe that the ending boundary should be
byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n" + boundary + "--\r\n");
(dashes on the end of the boundary, not at beginning -- though I've found that web servers may not care)...
|
|
|
|
 |
|
 |
Excellent, that works perfectly.
Perhaps the author should include it in the main code, it seems quite important for a "real use" beyond a working sample.
|
|
|
|
 |
|
 |
Hi I have two question about your code.
1 - You use UTF8 encoding for the postHeaderBytes and then use ASCII encoding for the final boundaryBytes. Is there a specific reason for using different encoding or do they effectly produce the same byte arrays for this situation?
2 - You use the DateTime.Now.Ticks.ToString("x") for the boundry string. Is there a specific reason for using this? Can any string be used for the boundry?
Thanks for the article.
|
|
|
|
 |