Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2004-08-10
16
Medium Priority
?
403 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses

688 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