Solved

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

Posted on 2004-08-10
16
399 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
ID: 11763866
myWebClient.UploadFile("http://www.myserver.com/whatever.aspx", "POST", "c:\test.txt")
0
 
LVL 1

Author Comment

by:fulg0re
ID: 11763934
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
ID: 11764048
are there other form field values that might need to be set ?
0
Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

 
LVL 1

Author Comment

by:fulg0re
ID: 11764064
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
ID: 11764160
there is also a hidden on that page MAX_FILE_SIZE
0
 
LVL 37

Expert Comment

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

Author Comment

by:fulg0re
ID: 11764183
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
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11764270
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
ID: 11764335
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
ID: 11804524
Ok. My question is still unanswered, let's lift the points a little.
Anyone?
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11804593
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
ID: 11808284
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
ID: 11809322
ok. found solution myself
0
 
LVL 1

Author Comment

by:fulg0re
ID: 11818699
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
ID: 11859449
Closed, 450 points refunded.
Netminder
Site Admin
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

820 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