Solved

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

Posted on 2004-08-10
16
394 Views
Last Modified: 2008-03-10
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?
0
Comment
Question by:fulg0re
  • 8
  • 6
16 Comments
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
myWebClient.UploadFile("http://www.myserver.com/whatever.aspx", "POST", "c:\test.txt")
0
 
LVL 1

Author Comment

by:fulg0re
Comment Utility
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
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
are there other form field values that might need to be set ?
0
 
LVL 1

Author Comment

by:fulg0re
Comment Utility
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
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
there is also a hidden on that page MAX_FILE_SIZE
0
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
<input type="hidden" name="MAX_FILE_SIZE" value="512000" />
0
 
LVL 1

Author Comment

by:fulg0re
Comment Utility
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
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
 
LVL 1

Author Comment

by:fulg0re
Comment Utility
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
 
LVL 1

Author Comment

by:fulg0re
Comment Utility
Ok. My question is still unanswered, let's lift the points a little.
Anyone?
0
 
LVL 37

Expert Comment

by:gregoryyoung
Comment Utility
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
 
LVL 1

Author Comment

by:fulg0re
Comment Utility
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
 
LVL 1

Author Comment

by:fulg0re
Comment Utility
ok. found solution myself
0
 
LVL 1

Author Comment

by:fulg0re
Comment Utility
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
 
LVL 5

Accepted Solution

by:
Netminder earned 0 total points
Comment Utility
Closed, 450 points refunded.
Netminder
Site Admin
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now