Uploading a file from client to a webpage using POST with WebClient

Good day.
I'm having troubles figuring out how to use the UploadFile function in the WebClient class.
I want to be able to upload file to some site which has an HTML POST form. I'm testing against www.imageark.net
The form has a 'file' type field, which I somehow have to fill.
No idea how to do it.
Any suggestions?
LVL 1
fulg0reAsked:
Who is Participating?
 
NetminderConnect With a Mentor Commented:
Closed, 450 points refunded.
Netminder
Site Admin
0
 
gregoryyoungCommented:
myWebClient.UploadFile("http://www.myserver.com/whatever.aspx", "POST", "c:\test.txt")
0
 
fulg0reAuthor Commented:
that's exacly the approach that i'm using. but the problem is - the file doesn't get uploaded, and as a response I get the upload page back to me (the one with the form).
i suppose i have to craft a post request specifing the form field name and content of the file some other way.
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
gregoryyoungCommented:
are there other form field values that might need to be set ?
0
 
fulg0reAuthor Commented:
No, just the 'file'. Here's the snippet from form's html:
<form enctype="multipart/form-data" action="upload.php" method="post">
<input name="userfile" type="file" style="width: 80%;">

and etc.
0
 
gregoryyoungCommented:
there is also a hidden on that page MAX_FILE_SIZE
0
 
gregoryyoungCommented:
<input type="hidden" name="MAX_FILE_SIZE" value="512000" />
0
 
fulg0reAuthor Commented:
you're right, that's actually part of the question: can i use WebClient to forge a correct POST request with all needed fields filled (userfile,MAX_FILE_SIZE and etc).
0
 
gregoryyoungCommented:
WebClient.UploadValues ... lemme see if there is a way to push up a file while using UploadValues ... if not you'll have to use the actual Request/Response objects.
0
 
fulg0reAuthor Commented:
thanks. actually I have nothing against using the usual Request class... If only I had any clue on how to accomplish this task with it ;)
0
 
fulg0reAuthor Commented:
Ok. My question is still unanswered, let's lift the points a little.
Anyone?
0
 
gregoryyoungCommented:
the methods I have seen have looked like this ...

oHttpWebRequest = WebRequest.Create(oUri)  
 
oHttpWebRequest.Headers.Add("JSESSIONID:" & sJsessionId)  
 
oHttpWebRequest.CookieContainer = oCookieContainer  
 
oHttpWebRequest.ContentType = "multipart/form-data; boundary=" + sBoundary  
 
'*** Next build the post message.  
 
'***   This message needs to contain the boundary string  
 
'***   followed by content headers, Content-Disposition and Content-Type,  
 
'***   an empty line, the file contents, and a trailing boundary string.  
 
'// Build up the post message header  
 
oStringBuilder = New StringBuilder  
 
With oStringBuilder  
 
.Append("--")  
 
.Append(sBoundary)  
 
.Append(vbCrLf)  
 
'Append("Content-Disposition: form-data; name=\"consultationId\";");  
 
.Append(vbCrLf)  
 
.Append(vbCrLf)  
 
.Append(sConsultationId)  
 
.Append("--")  
 
.Append(sBoundary)  
 
.Append(vbCrLf)  
 
.Append("Content-Disposition: form-data; name=" & DblQuote("totalImageCount") & ";")  
 
.Append(vbCrLf)  
 
.Append(vbCrLf)  
 
.Append(iImageCount)  
 
.Append("--")  
 
.Append(sBoundary)  
 
.Append(vbCrLf)  
 
'.Append("Content-Disposition: form-data; name=\"file\"; filename=\"");  
 
.Append("Content-Disposition: form-data; name=" & DblQuote("file") & "; filename=" & DblQuote(sImageFullPathAndFileName))  
 
'.Append(Path.GetFileName(sImageFileName))  
 
.Append(vbCrLf)  
 
.Append("Content-Type: application/octet-stream")  
 
.Append(vbCrLf)  
 
.Append(vbCrLf)  
 
End With  
 
Dim sPostHeader As String = oStringBuilder.ToString()  
 
Dim saPostHeaderBytes As Byte() = Encoding.UTF8.GetBytes(sPostHeader)  
 
''// Build the trailing boundary string as a byte array  
 
''// ensuring the boundary appears on a line by itself  
 
Dim saPostTrailingBoundaryBytes As Byte() = Encoding.ASCII.GetBytes(vbCrLf & "--" + sBoundary + vbCrLf)  
 
''// Before we can gain access to the request stream,  
 
''//   we need to calculate the content length.  
 
''//   The content length is the number of bytes in our  
 
''//   post header, file, and trailing boundary string.  
 
Dim oFileStreamReader As FileStream = New FileStream(sImageFullPathAndFileName, FileMode.Open, FileAccess.Read)  
 
Dim lLength As Long = saPostHeaderBytes.Length + oFileStreamReader.Length + saPostTrailingBoundaryBytes.Length  
 
oHttpWebRequest.ContentLength = lLength  
 
oHttpWebRequest.Method = "POST"  
 
oHttpWebRequest.AllowWriteStreamBuffering = True  
 
oGetRequestStream = oHttpWebRequest.GetRequestStream()  
 
''// Write out our post header  
 
oGetRequestStream.Write(saPostHeaderBytes, 0, saPostHeaderBytes.Length)  
 
'// http://vetmacs.vmth.ucdavis.edu/echo 
 
'// Open the local file  
 
'Dim oFileStreamReader As FileStream = New FileStream(sImageFullPathAndFileName, FileMode.Open)  
 
'// Allocate byte buffer to hold file contents  
 
'// byte[] inData = new byte[4096];  
 
Dim saBufferBytes() As Byte = New Byte(4096) {}    ' inData  
 
'// loop through the local file reading each data block  
 
'//  and writing to the request stream buffer  
 
Dim iBytesRead As Int32 = oFileStreamReader.Read(saBufferBytes, 0, saBufferBytes.Length)  
 
'While (iBytesRead > 0)  
 
While (oFileStreamReader.Position < oFileStreamReader.Length)  
 
oGetRequestStream.Write(saBufferBytes, 0, iBytesRead)  
 
iBytesRead = oFileStreamReader.Read(saBufferBytes, 0, saBufferBytes.Length)  
 
End While  
 
oGetRequestStream.Write(saPostTrailingBoundaryBytes, 0, saPostTrailingBoundaryBytes.Length)  
 
oFileStreamReader.Close()  
 
oGetRequestStream.Close()   '// ERROR OCCURS HERE !  
 
'// Finally, we send the request and await the response.  
 
oHttpWebResponse = oHttpWebRequest.GetResponse  
 
oStream = oHttpWebResponse.GetResponseStream  
 
oReader = New StreamReader(oStream)  
 
sOutput = oReader.ReadToEnd  
 
oReader.Close()  
 
oStream.Close()  
 
oHttpWebRequest = Nothing  
 
oHttpWebResponse.Close()
0
 
fulg0reAuthor Commented:
1st. the code is in VB! :)
2nd. check out the line:
oGetRequestStream.Close()   '// ERROR OCCURS HERE !  

I've converted the code to C#, and the error DOES occur there! :)

I suppose that code was pasted from some other question on the issue? ;)
0
 
fulg0reAuthor Commented:
ok. found solution myself
0
 
fulg0reAuthor Commented:
here's the code:

static void FileUpload2(string url, string filename)
{

    string dataBoundary = "--xyz";
    // you will need to change the URL to point to your box
    HttpWebRequest Req =(HttpWebRequest)WebRequest.Create(url);
    Req.UserAgent = "Upload Test";
    Req.ContentType = "multipart/form-data; boundary=xyz";
    Req.Method = "POST";
    Req.KeepAlive = true;
    byte[] FileData = File.ReadAllBytes(filename);
    string FileStr = Convert.ToBase64String(FileData);
    StringBuilder DataString = new StringBuilder();
    StringBuilder DataString2 = new StringBuilder();
    DataString.Append(dataBoundary + "\r\n");

    DataString.Append("Content-Disposition: form-data; name=\"userfile\"; filename=\"File1.jpg\"\r\n");
    DataString.Append("Content-Length: " + FileData.Length.ToString() + "\r\n");
    DataString.Append("Content-Type: image/jpeg\r\n\r\n");
    byte[] tmpPostdata1 = System.Text.Encoding.Default.GetBytes(DataString.ToString());
    DataString2.Append(dataBoundary + "\r\n\r\n");
    DataString2.Append("Content-Disposition: form-data; name=\"MAX_FILE_SIZE\"\r\n\r\n512000\r\n\r\n");
    DataString2.Append(dataBoundary + "--\r\n");
    byte[] tmpPostdata2 = System.Text.Encoding.Default.GetBytes(DataString2.ToString());
    byte[] t = new byte[tmpPostdata1.Length + FileData.Length +  tmpPostdata2.Length];
    tmpPostdata1.CopyTo(t, 0);
    FileData.CopyTo(t,tmpPostdata1.Length);
    tmpPostdata2.CopyTo(t, tmpPostdata1.Length + FileData.Length);
    string tmp = System.Text.Encoding.Default.GetString(t);
    Req.ContentLength = t.Length;
    Req.Referer = "http://www.imageark.net/";
    Stream tempStream = Req.GetRequestStream();
    // write the data to be posted to the Request Stream
    tempStream.Write(t,0,t.Length);
    tempStream.Close();
    HttpWebResponse Resp = (HttpWebResponse)Req.GetResponse();
    //Read the raw HTML from the request
    StreamReader sr = new StreamReader(Resp.GetResponseStream(),
        Encoding.Default);
    //Convert the stream to a string
    string s = sr.ReadToEnd();
    sr.Close();
    Resp.Close();
    Console.WriteLine(s);
}
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.