Solved

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

Posted on 2004-08-10
16
398 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
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 
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

ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

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

Suggested Solutions

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

832 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