[VB.NET] MultiPart-HttpWebRequest (Upload)

10/19/2012 14:17 Kraizy​#1
Hier mal ein kleines Beispiel wie man mit HttpWebRequest eine Datei hochladen kann, in diesem Fall ein Bild auf epvpimg.com.

Vom Prinzip her funktioniert ein MultiPart Request eigentlich genauso wie ein normaler Request auch, man muss einfach den Post-String, welches im LiveHttpHeaders angezeigt wird, nachbilden.

Da ich hier: [Only registered and activated users can see links. Click Here To Register...] bereits ein Tutorial über WebRequest erstellt habe, werde ich in diesem Thread nicht mehr so genau darauf eingehen und alles detailiert erklären.

Die Funktion für einen Upload könnte z.B. so aussehen:

PHP Code:
Public Function GetUploadResponse(ByVal url As StringByVal upload As UploadData) As String
     Dim boundary 
As String Guid.NewGuid().ToString().Replace("-""")
     
Dim request As HttpWebRequest CType(HttpWebRequest.Create(url), HttpWebRequest)
     
request.Method "POST"
     
request.ContentType "multipart/form-data; boundary=" boundary
     request
.UserAgent "Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20100101 Firefox/15.0.1"

     
Dim PostData As New MemoryStream
     With 
New StreamWriter(PostData)
          .
Write(("--" boundary) & vbNewLine)
          .
Write("Content-Disposition: form-data; name=""{0}""; filename=""{1}""{2}"upload.FieldNameupload.FileNamevbNewLine)
          .
Write(("Content-Type: " GetContentType(upload.FileName) & vbNewLine) & vbNewLine)
          .
Flush()
          .
Write(vbNewLine)
          .
Write("--{0}--{1}"boundaryvbNewLine)
          
PostData.Write(upload.Content0upload.Content.Length)
          .
Flush()
     
End With

     request
.ContentLength PostData.Length
     Using s 
As Stream request.GetRequestStream()
          
PostData.WriteTo(s)
          
End Using
     PostData
.Close()

     Return New 
StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd()
End Function 
"UploadData" ist lediglich eine kleine Struktur, die unsere nötigen Werte enthält:

PHP Code:
Structure UploadData
     Dim Fieldname 
As String
     Dim Filename 
As String
     Dim Content 
As Byte()

     Public 
Sub New(ByVal fieldname As StringByVal filename As StringByVal content As Byte())
          
Me.Fieldname fieldname
          Me
.Filename filename
          Me
.Content content
     End Sub
End Structure 
Und dann noch die kleine Funktion "GetContentType", die für uns überprüft, welche Dateiendung unser Bild hat und dementsprechend den nötigen Wert für unseren Request zurückgibt:

PHP Code:
Public Function GetContentType(ByVal path As String) As String
     Select 
Case New FileInfo(Path).Extension.ToLower()
          Case 
".bmp"
               
Return "image/bmp"
          
Case ".gif"
               
Return "image/gif"
          
Case ".jpe"".jpeg"".jpg"
               
Return "image/jpeg"
          
Case ".png"
               
Return "image/png"
          
Case ".svg"
               
Return "image/svg+xml"
          
Case ".tif"".tiff"
               
Return "image/tiff"
          
Case Else
               Return 
"application/octet-stream"
     
End Select
End 
Function 
So, das einzige was wir nun noch brauchen ist unser Post-String. Dazu einfach wie im 1. Tutorial bereits erklärt, LiveHttpHeaders öffnen und ein Bild hochladen, Ergebnis:

[Only registered and activated users can see links. Click Here To Register...]

Unsere Anfrage wird also an [Only registered and activated users can see links. Click Here To Register...] geschickt.
Die nötigen Werte für den Post-String sind:

-----------------------------114782935826962
Dies wird automatisch in der GetUploadResponse-Funktion generiert (unsere "boundary"-Variable).

Content-Disposition: form-data; name="files[]"; filename="b.jpg"
files[] -> Fieldname (in unserer UploadData-Struktur)
b.jpg -> Filename (in unserer UploadData-Struktur)

Content-Type: image/jpeg
Dies erledigt unsere GetContentType-Funktion.

So, demnach würde unser Request folgendermaßen aussehen:

PHP Code:
//Beim Klick auf einen Button oder sonst was...
With New Http
     Dim upload 
As New Http.UploadData("files[]""PfadZumBild"File.ReadAllBytes("PfadZumBild"))
     
Dim html As String = .GetUploadResponse("http://epvpimg.com/upload/"upload)
End With 
Sollte unser Upload nun erfolgreich gewesen sein, so bekommen wir als Antwort folgendes (in der "html" Variable):

Quote:
"[{"name":"b.jpg","size":35200,"type":"image\/jpeg","url":"http:\/\/epvpimg.com\/U9zFd","thumbnail_url":"http:\/\/i.epvpimg.com\/U9zFd.jpg","alphaid":"U9zFd","extension":".jpg"}]"
Nun können wir z.B. ganz einfach mit der Split-Funktion (gibt natürlich auch andere Möglichkeiten) den Wert für "alphaid" auslesen und schon haben wir den Link zum Bild:

PHP Code:
Dim alphaid As String html.Substring(html.IndexOf("alphaid")).Split(""""c)(2)
//alphaid hat nun den Wert U9zFd
//daraus bilden wir nun den Link
Dim url As String "http://epvpimg.com/" alphaid 
Ja, das war's eigentlich auch schon, im Anhang findet ihr noch ein kleines Beispielprojekt:


[Only registered and activated users can see links. Click Here To Register...]

Hoffe ich konnte damit einigen weiterhelfen.

Kraizy
10/19/2012 18:56 Shawak#2
Schönes Tutorial, gut erklärt.
10/19/2012 19:26 Kraizy​#3
Danke :)
10/29/2012 23:50 hound1#4
great tutorial, I will try this out sometime
10/30/2012 19:18 Kraizy​#5
Have fun :P
11/02/2012 19:07 'xLeatz.#6
Gute Fortsetzung des anderen Tutorials. :)
11/03/2012 11:57 Kraizy​#7
Danke :)
11/03/2012 13:59 tolio#8
Mir persöhnlich zwar nichts neues aber wirklich mal ein schönes und vorallem ECHTES tutorial und kein "hier ist der code, gebt mir ein thanks"-Thread
Danke dafür.
11/14/2012 15:28 TheUltratester123#9
Gut erklärt und werde ich mir mal genauer anschauen
10/24/2013 20:16 EvolutionClip#10
Gutes Tutorial, ich hab allerdings eine Frage, und zwar möchte ich einen Post senden und eine Datei hochladen, also eine Mischung aus beiden Tutorials eine HTML form würde so aussehen:
<form action="http://domain.tld/post.php"
method="post"
enctype="multipart/form-data">
<input type="text" name="username" value="">
<input type="password" name="password" value="">
<input type="file" name="file">
</form>

Ich weiß allerdings nicht wie ich das in VB realisieren kann eigentlich müsste es so sein wie in diesem Tutorial bloß man muss noch den Post hinzufügen, aber irgendwie weiß ich nicht wo
10/24/2013 20:30 tolio#11
eine datei hochladen ist ein post
schau dir das erste bild an, da sieht mans in livehttpheaders
du musst halt zusätzliche felder einfach entsprechend anhängen
10/24/2013 20:40 EvolutionClip#12
Quote:
Originally Posted by tolio View Post
eine datei hochladen ist ein post
schau dir das erste bild an, da sieht mans in livehttpheaders
du musst halt zusätzliche felder einfach entsprechend anhängen
Ja, soweit ist mir das klar ich habe jetzt allerdings das Problem/bzw verstehe nicht ganz, wie ich es machen soll. ich hab mit das mal in HTTP live header angeschaut(meine Version) seiht so aus
Code:
DNT: 1
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------10778313689980
Content-Length: 4875
-----------------------------10778313689980
Content-Disposition: form-data; name="username"

123
-----------------------------10778313689980
Content-Disposition: form-data; name="password"

456
-----------------------------10778313689980
Content-Disposition: form-data; name="captchafile"; filename="captcha_display.png"
Content-Type: image/png

PNG//HIER DAS BILD

und der Content-Type ist jetzt multipart, das verwirt mich ein bisschen
10/24/2013 21:23 tolio#13
sieht doch oben im thread ganz genau so aus, ist auch nen multipart request, steht sogar im thread titel ;)
12/04/2013 07:00 ҳc3ρ0™#14
Mir gefällt das Tutorial ;)