.NET
VB.NET: Bilder Hochladen mit der TwitPic API Teil 3
Posted on .In dem dritten Teil der API-Reihe möchte ich euch zeigen wie man mit Hilfe der TwitPic API Bilder hochladen kann.
Diesesmal schreibt die API vor, dass man POST-Requests verwendet um der Seite Daten zu senden. Das macht die Sache etwas komplizierter, und dazu kommt noch, dass wir auch noch ein Bild verschicken müssen, also müssen auchnoch binäre Daten verschickt werden. Aber langsam, erstmal die Theorie!
Ihr kennt doch sicher die normalen Eingabemasken wie zB. die von imageshack.us. Diese besteht aus einem Dateiauswahlfeld, mehreren Checkboxen und einem Textfeld. Wer schonmal HTML gemacht hat wird wissen dass dieses Gebilde aus so genannten Interaktiven Elementen ein Formular darstellt welches nach dem Betätigen des Senden-Buttons an eine vorher definierte Adresse gesendet wird!
Dabei sendet der Browser einen HTTP POST-Request an den Server. Ein solcher Request besteht für gewöhnlich aus einem Kopf, den Daten und einem Fuß. So könnte zB. ein HTTP POST-Request aussehen:
POST /wiki/Spezial:Search HTTP/1.1
Host: de.wikipedia.org
Content-Type: application/x-www-form-urlencoded
Content-Length: 24
search=Katzen&go=Artikel
Der Server verwertet diese Daten dann und schickt eine Antwort. Je nachdem wie wir angefragt haben bekommen wir als Antwort eine XML-Struktur (Wie in den Letzten Beispielen) oder eine HTML Struktur. Die Kommunikation geschieht dabei auf dem HTTP Port 80 und läuft über das TCP Protokoll!
In den letzten beiden Teilen haben wir jeweils so genannte GET-Requests erstellt, bei denen nur der URL-Strang mit den Variablen versandt wurde.
Da wir aber nun ein Bild übertragen wollen, müssen wir versuchen ein POST-Request-Objekt zu erstellen, das wir dann an den TwitPic Server schicken können.
Unser POST-Objekt muss dabei folgende Daten übermitteln:
- Unseren Twitter Benutzernamen
- Unser Twitter Passwort
- Das Bild das wir einstellen wollen
Wenn wir diese Daten nun in unser Objekt verfrachten, müssen wir dafür sorgen, dass der Server später weis, was was ist und die Daten von einander trennen kann. Deswegen müssen wir für jeden Eintrag einen eigenen Head und Body erzeugen.
Das Bild muss dann auch in das binäre Format umgewandelt werden und dann mit den anderen Daten durch ein Strom an den Server gesendet werden! – Hört sich kompliziert an, ich weis aber es hält sich in Grenzen!
Hier erstmal der Code für das Hochladen des Objekts mit allen Daten und der Abruf der Antwort. Tipp: Ihr könnt den Code besser lesen, wenn ihr auf den Knopf oben rechts in der Code Darstellung klickt!
Public Function uploadPic(ByVal pic As Byte(), ByVal filename As String, ByVal user As String, ByVal pass As String) Dim encoding As String = "iso-8859-1" 'Erzeugen einer einzigartigen identifikation Dim gui As String = Guid.NewGuid().ToString() 'Diese wird für den Header und den footer der Daten benötigt Dim head As String = String.Format("--{0}", gui) Dim foot As String = String.Format("--{0}--", gui) 'Einen Stringbuilder erstellen, in dem wir nun bequem die 'benötigten POST Daten speichern können Dim contents As StringBuilder = New StringBuilder() 'Benutzerdaten schreiben (benutzername) contents.AppendLine(head) contents.AppendLine(String.Format("Content-Disposition: form-data; name=""{0}""", "username")) contents.AppendLine() contents.AppendLine(user) 'Benutzerdaten schreiben (passwort) contents.AppendLine(head) contents.AppendLine(String.Format("Content-Disposition: form-data; name=""{0}""", "password")) contents.AppendLine() contents.AppendLine(pass) 'Header schreiben contents.AppendLine(head) 'Bildinformationen schreiben, Bildkopf und die Binärdaten Dim fileHeader As String = String.Format("Content-Disposition: file; name=""{0}""; filename=""{1}""", "media", filename) Dim fileData As String = System.Text.Encoding.GetEncoding(encoding).GetString(pic) 'Informationen zu dem Übergebenen Dateityp schreiben contents.AppendLine(fileHeader) contents.AppendLine(String.Format("Content-Type: {0}", "image/jpeg")) contents.AppendLine() contents.AppendLine(fileData) 'Durch schreiben des footers signalisieren dass keine Daten mehr kommen contents.AppendLine(foot) MessageBox.Show(contents.ToString) 'Stream Reader zum lesen der Antwort von Twitpic Dim reader As StreamReader Dim result As String Dim response As HttpWebResponse 'Einen Webrequest zu der TwitPic API erstellen Dim request As HttpWebRequest = WebRequest.Create("http://twitpic.com/api/upload") 'Die Auflagen die in der API beschreiben sind erfüllen: 'API-Zitat: '--- 'Fields to post in: '(post data should be formatted as multipart/form-data) '--- request.ContentType = String.Format("multipart/form-data; boundary={0}", gui) request.Method = "POST" 'Die Daten die noch im Stringbuilder als String vorliegen 'in das byte (Binär)-Format umwandeln, damit die API diese annimt Dim bytes As Byte() = System.Text.Encoding.GetEncoding(encoding).GetBytes(contents.ToString()) request.ContentLength = bytes.Length 'Einen Stream aus dem WebRequest erstellen Dim writer As Stream = request.GetRequestStream() 'Die Binären Daten in den Strom schreiben writer.Write(bytes, 0, bytes.Length) response = request.GetResponse() 'Antwort von Twitpic empfangen reader = New StreamReader(response.GetResponseStream) result = reader.ReadToEnd reader.Close() Return result End Function
Wenn ihr diesen Code ausführt, wird ein POST-Objekt erzeugt und an den TwitPic Server gesendet. Dabei werden diese Informationen übermittelt. (Bild 1)
Man sieht ganz klar die Aufteilung. Der Kopf der aus der UID und den Meta Daten besteht und der Body, der nur den Wert beinhaltet.
Das Bild das ich hier sende hat einen etwas größeren Kopf, scheint dafür aber einen sehr kleinen Body zu haben. Ich kann euch beruhigen, das ist nur so, weil Windows, oder das MessageBox Objekt keine Binäre Darstellung von Zeichen beherrscht.
Eigentlich kommt dadrunter noch ein Footer (Fuß), aber dieser wird wegen der binären Daten abgeschnitten!
Natürlich bekommt man auch eine Antwort, in diesem Fall eine im XML-Format. Diese beinhaltet entweder die Erfolgsmeldung oder eine Fehlermeldung mit einer Kurzen Beschreibung, woran es lag. An Bild 2 könnt ihr erkennen wie so ein Fehler aussehen könnte!
Wenn kein Fehler kommt steht dort dementsprechend die URL zum Bild statt der Fehlermeldung!
Wenn ihr nicht direkt den Code versteht ist das nicht schlimm. Man sollte ersteinmal wissen was der Browser da bei jedem Klick eigentlich hin- und herschickt. Dazu kann ich den Wikipedia-Artikel empfehlen. Es schadet auch nicht, weitere Beispiele anzuschauen bei denen mit HTTPWebRequest gearbeitet wird. ZB Hier oder Hier. (leider alles in C#)
Zum Schluss sei hier noch gesagt, dass die TwitPic API noch weitere Möglichkeiten bietet, wie zB. das Anfertigen von Vorschaubildern oder das Anhängen von Tweets an das Bild sodass automatisch auch euer Twitter Status mit dem neuen Bild aktualisiert wird!
Bild 3: Das Demoprojekt in Aktion
Wie immer könnt ihr euch auch das Demoprojekt herunterladen: Download
Ich hoffe das Beispiel hat euch gefallen und freue mich auf euer Feedback!
Sebastian Gross
http://www.bigbasti.comSebastian Gross arbeitet in Bielefeld als Softwareentwickler für .NET und Java im Bereich Web.Als Fan der .NET-Plattform lässt er sich kein Userguppen Treffen und Community Event im Raum OWL entgehen.Dabei hat er eine besondere Vorliebe für das ASP.NET MVC Framework und für das Test Driven Development (TDD) entwickelt.
Author Pascal Raszyk
Posted at 10:12 26. Januar 2010.
Sehr schöner Artikel. Habe schon seit längerem so etwas gesucht.
Wird die Verbindung über Sockets hergestellt?
Author admin
Posted at 15:38 26. Januar 2010.
Hallo Pascal,
ja die Kommunikation verläuft hierbei über TCP und hier werden die Verbindungen über Sockets geregelt. Also ja. 🙂
MfG, Basti