.NET: Mit Extension Methods arbeiten
Aus gegebenen Anlass möchte ich heute einen kleinen Artikel zu dem Thema Extension Methods in .NET schreiben, einfach nur weil es eine sehr simple Möglichkeit bietet sich das Leben zu erleichtern. Falls es euch nichts sagt, mit Extension Methods, die es seit C# 3.0 gibt ist es möglich bestehende Klassen, sogar interne Core-Klassen wie Integer oder String mit eigenen Methoden zu erweitern.
Wieso das nützlich ist fragst du dich? Na ganz einfach, habt ihr schon mal die Methode String.toInt32() vermisst? Diese ist nur eine (sehr simple) Methode, die man häufiger gebrauchen könnte, die es aber nicht gibt. Diese könnte man sehr einfach mit einer Extension Method erweitern.
Als Beispiel möchte ich hier aber den Artikel von vor ein paar Tagen nehmen, wo wir eine Methode erstellt haben mit der man ein XmlElement in einem XmlDocument umbenennen konnte. Dies mussten wir machen, da die Klasse XmlDocument keine Methode dafür anbietet. Nun wollen wir mal die XmlDocument Klasse um diese Methode erweitern.
Das ganze funktioniert sehr einfach:
public static class XmlDocumentExtension
{
public static bool RenameXmlElement(this XmlDocument doc,
XmlElement oldElement,
string newName) {
try {
//Neues XmlElement mit neuem namen anlegen
XmlElement newElement = oldElement.OwnerDocument.CreateElement(newName);
//Dem neuen XmlElement alle Attribute des alten Elements übergeben
foreach (XmlAttribute a in oldElement.Attributes) {
newElement.SetAttributeNode((XmlAttribute)a);
}
//Dem neuen XmlElement alle Kinder Elemente des alten Elements anhängen
foreach (XmlNode n in oldElement.ChildNodes) {
newElement.AppendChild(n.Clone());
}
oldElement.ParentNode.ReplaceChild(newElement, oldElement);
} catch {
return false;
}
return true;
}
}
Wir legen eine ganz normale Klasse an, diese kann heißen wie man will, ich habe sie hier nur zum besseren Verständnis so benannt. In der klasse legen wir nun die Funktion an um die wir unsere Klasse erweitern wollen. Hierbei ist wichtig, dass sowohl die Klasse als auch die Funktion als public und static markiert wird. Des Weiteren sollte man einen Verweis auf System.Code.dll setzen.
Bei der Deklaration der Funktion muss man dann angeben welche Klasse erweitert werden soll. Hier erweitern wir die Klasse XmlDocument weswegen vor diesem Parameter noch ein this steht. Dieser Parameter wird nur dazu benötigt und muss dann später bei dem Aufruf der Funktion nicht gesetzt werden.
Bild 1: Auch IntelliSense erkennt unsere Erweiterung an und bietet diese an
Natürlich bleibt die "original" Klasse XmlDocument unberührt von dieser Aktion und wird nur virtuell erweitert. Diese Erweiterung ist natürlich auch nur für das Aktuelle Projekt nutzbar.
Ich finde dieses Feature wirklich sehr nützlich und kann es euch deswegen auch nur empfehlen.
XmlElement oldElement,
string newName) {
try {
//Neues XmlElement mit neuem namen anlegen
XmlElement newElement = oldElement.OwnerDocument.CreateElement(newName);
//Dem neuen XmlElement alle Attribute des alten Elements übergeben
foreach (XmlAttribute a in oldElement.Attributes) {
newElement.SetAttributeNode((XmlAttribute)a);
}
//Dem neuen XmlElement alle Kinder Elemente des alten Elements anhängen
foreach (XmlNode n in oldElement.ChildNodes) {
newElement.AppendChild(n.Clone());
}
oldElement.ParentNode.ReplaceChild(newElement, oldElement);
} catch {
return false;
}
return true;
}
XML: Den Namen eines XmlNode Aendern
Wenn man unter .NET mit XML Dokumenten arbeitet, nimmt man sehr oft Änderungen am Dokument vor. Doch letztens ist mir aufgefallen, dass eine der einfachsten Änderungen garnicht so einfach ist, nämlich wenn man den Namen eines XmlNode ändern will. Also die XmlNode.Name Eigenschaft.
Denn wenn man mal einen Blick ins MSDN wirft wird man feststellen, dass diese Eigenschaft read-only ist! Das ist natürlich blöd, da man nun keinen einfachen Weg hat den Namen des Knotens zu ändern.
Wenn man diesen aber unbedingt ändern will muss man das über einen kleinen Umweg machen. Man muss ein neues XmlElement erstellen und dabei den Namen ändern, anschließend noch alle Attribute und Kinder-Elemente des alten Elements übernehmen und an der Stelle des alten wieder in das XmlDocument einfügen.
Bild 1: Struktur & Änderungswunsch
Konkret sieht das Ganze so aus: C#
private void Form1_Load(object sender, EventArgs e) {
//XmlDomument erstellen und eine Xml-Datei laden
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(Application.StartupPath + "\\xml.xml");
//Zur Demonstration die alte XML-Struktur ausgeben
System.Console.WriteLine(xmlDoc.OuterXml);
//Das Element das umbenannt werden soll heraussuchen
XmlElement oldElement = (XmlElement)xmlDoc.GetElementsByTagName("books")[0];
//Das herausgesuchte Element mit einem neuen Namen klonen
XmlElement newElement = renameXmlElement(oldElement, "my-books");
//Das alte Element mit dem neuen ersetzen
oldElement.ParentNode.ReplaceChild(newElement, oldElement);
//Kontrolle: Die neue Struktur ausgeben
System.Console.WriteLine(xmlDoc.OuterXml);
xmlDoc.Save(Application.StartupPath + "\\xml.xml");
}
public static XmlElement renameXmlElement(XmlElement e, string newname) {
//Neues XmlElement mit neuem namen anlegen
XmlElement newElement = e.OwnerDocument.CreateElement(newname);
//Dem neuen XmlElement alle Attribute des alten Elements übergeben
foreach (XmlAttribute a in e.Attributes) {
newElement.SetAttributeNode((XmlAttribute)a);
}
//Dem neuen XmlElement alle Kinder Elemente des alten Elements anhängen
foreach (XmlNode n in e.ChildNodes) {
newElement.AppendChild(n.Clone());
}
//Das neue XmlElement zurückgeben
return newElement;
}
Und hier das Ganze noch mal in VB.NET:
Private Sub Form1_Load(sender As Object, e As EventArgs)
'XmlDomument erstellen und eine Xml-Datei laden
Dim xmlDoc As New XmlDocument()
xmlDoc.Load(Application.StartupPath + "\xml.xml")
'Zur Demonstration die alte XML-Struktur ausgeben
System.Console.WriteLine(xmlDoc.OuterXml)
'Das Element das umbenannt werden soll heraussuchen
Dim oldElement As XmlElement = DirectCast(xmlDoc.GetElementsByTagName("books")(0), XmlElement)
'Das herausgesuchte Element mit einem neuen Namen klonen
Dim newElement As XmlElement = renameXmlElement(oldElement, "my-books")
'Das alte Element mit dem neuen ersetzen
oldElement.ParentNode.ReplaceChild(newElement, oldElement)
'Kontrolle: Die neue Struktur ausgeben
System.Console.WriteLine(xmlDoc.OuterXml)
xmlDoc.Save(Application.StartupPath + "\xml.xml")
End Sub
Public Shared Function renameXmlElement(e As XmlElement, newname As String) As XmlElement
'Neues XmlElement mit neuem namen anlegen
Dim newElement As XmlElement = e.OwnerDocument.CreateElement(newname)
'Dem neuen XmlElement alle Attribute des alten Elements übergeben
For Each a As XmlAttribute In e.Attributes
newElement.SetAttributeNode(DirectCast(a, XmlAttribute))
Next
'Dem neuen XmlElement alle Kinder Elemente des alten Elements anhängen
For Each n As XmlNode In e.ChildNodes
newElement.AppendChild(n.Clone())
Next
'Das neue XmlElement zurückgeben
Return newElement
End Function
Kompliziert ist es natürlich nicht, aber trotzdem etwas ärgerlich, dass man diese Methode dann doch selber implementieren muss.
VB.NET: FitzBox IP erneuern ueber uPnP
Die FritzBox ist als Router weit verbreitet und bietet einen Haufen an Konfigurationsmöglichkeiten an. Eins der nützlichsten Features ist uPnP (Universal Plug and Play). Diese Schnittstelle bietet uns eine sehr bequeme Möglichkeit mit dem Gerät zu kommunizieren ohne dass man einen Benutzernamen oder ein Kennwort benötigt!
Wer öfter mal im Internet unterwegs ist, kennst sicherlich mehrere gute Gründe seine IP zu wechseln. Und das ist sehr einfach, denn alles was dafür nötig ist, ist eine erneute Einwahl ins Internet.
Dies kann man sehr einfach über die Benutzeroberfläche der FritzBox machen oder einfach "oldschool"-mäßig das Netzwerkkabel aus der FritzBox ziehen und wieder einstecken. (Letzteres erfordert ebenfalls keinen Benutzernamen und Passwort)
Doch wenn man des öfteren auf diese Funktionalität angewiesen ist, ist es doch relativ nervig und umständlich. Deswegen werden wir hier ein einfaches kleines Programm entwickeln, dass für uns den Router zu einer Neueinwahl ins Internet "zwingt".
Wie oben bereits erwöhnt heißt die Technologie dafür UPnP (Universal Plug and Play). Über diese Technologie lassen sich sehr viele Befehle an die Fritzbox senden, vorausgesetzt, man befindet sich in dem selben Netzwerk.
Von Statusabfragen über Auslastungen und Übertragung, lassen sich sogar Telefonnummern anwählen und Anrufe steuern, im Prinzip kann man alle Funktionen darüber ansteuern. Hier gibts eine nette Übersicht mit vielen Beispielen.
Wie werden die Anfragen eigentlich an die Fritzbox übertragen? Das geschieht sehr einfach über einen POST Aufruf, denn auf der Fritzbox (und auch auf den meisten anderen Routern) läuft ein kleiner Webserver denn man ganz einfach über den Browser erreicht, wenn man die adresse "fritz.box" in die Adresszeile tippt.
Dort ist die Fritzbox genauso aufgebaut wie eine gewöhnliche Webseite. Und diese nimmt auch POST und GET aufrufe entgegen. Genau hier setzen wir an und werden unsere Befehle rüber schicken.
Dim client As New TcpClient
client.Connect("fritz.box", 49000)
Dim stream As NetworkStream = client.GetStream
Dim bytes As Byte() = New Byte((My.Resources.msg.Length)) {}
bytes = Encoding.ASCII.GetBytes(My.Resources.msg)
stream.Write(bytes, 0, bytes.Length)
bytes = New Byte(1024) {}
Dim str As String = String.Empty
Dim count As Integer = stream.Read(bytes, 0, bytes.Length)
str = Encoding.ASCII.GetString(bytes, 0, count)
stream.Close()
client.Close()
Der Code ist sehr simpel, wir erstellen uns einen WebClient und verbinden uns mit der FritzBox. Nach der Verbindung senden wir ein POST Request raus und lesen anschließend die Antwort wieder aus.
Mit dem obigen Code senden wir folgenden Befehl an die Fritzbox:
POST /upnp/control/WANIPConn1 HTTP/1.1
HOST: fritz.box:49000
SOAPACTION: "urn:schemas-upnp-org:service:WANIPConnection:1#ForceTermination"
CONTENT-TYPE: text/xml ; charset="utf-8"
Content-Length: 293
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:ForceTermination xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1" />
</s:Body>
</s:Envelope>
Wie man sieht ist der Befehl ein gewöhnlicher POST Aufruf inkl. Header. Dieser übergibt einen Befehl urn:schemas-"upnp-org:service:WANIPConnection:1#ForceTermination", der der Fritzbox sagt die Verbindung ins Internet neu aufzubauen.
Man muss hierbei sehr aufpassen, besonders die Content-Length Angabe muss genaustens passen, da sonst ein Fehler als Antwort eintrudelt.
Wie immer gibts auch eine kleine Demoanwendung.
Download hier: Download [VS 2008 Projekt]
VB.NET: Bilder Hochladen mit der TwitPic API Teil 3
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&amp;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!
VB.NET: Kurze URLs erstellen mit bit.ly Teil 2
Wie bereits im letzten Beitrag angekündigt möchte ich in diesem Beispiel zeigen, wie man seine URLs mit dem Dienst bit.ly verkürzen kann.
Ersteinmal die Frage "warum überhaupt bit.ly? Ich habe doch tinyurl.com!"
Nun das ist einfach, denn bit.ly bietet einen größeren Featureumfang. Dawäre:
- Eigene Accounts
- Linkmonitoring (wie oft wurde mein Link geklickt)
- Statistiken
- Erweiterte Abfragen und Parameter
- Kürzerer Name (bit.ly = 6 Zeichen | tinyurl.com = 11 Zeichen)
Allgemein kann man sagen, bit.ly ist professioneller aufgelegt! Aber mit einem höherem Featureumfang wird die Benutzung der APIs auch etwas komplexer.
An die API-Dokumentation von bit.ly kommt man sehr einfach in dem man auf deren Homepage ganz unten auf "API" klickt und dann dem gezeigten Link folgt. Hier findet man eine Komplette Dokumentation aller Möglichkeiten.
Was direkt auffällt ist, dass es viele verschiedene Funktionen gibt und die URL die wir benutzen müssen viel länger ist.
Das was aber auch sehr wichtig ist, ist dass man diesen Dienst nicht anonym benutzen kann, sondern sich einen Account erstellen muss um einen Sogenannten API-Key zu erhalten. Das ist hauptsächlich dafür da, um Missbrauch der Seite zu verhindern (zB. Spam).
Die Registrierung geht sehr schnell nach der Eingabe von Benutzername, E-Mail und Passwort. Wenn mann dann eingeloggt ist muss man folgende Seite aufrufen: http://bit.ly/account/your_api_key/ hier findet man seinen API-Schlüssel, den man unbedingt braucht, um URLs zu generieren, also aufschreiben!
ACHTUNG: In meinem Beispiel hier verwende ich den Demo-API-Schlüssel von bit.ly, der auch in der Doku steht. Wenn ihr was eigenes macht müsst ihr euch unbedingt registrieren!
Hat man das einmal geschafft kann man mit dem Programmieren loslegen:
Public Function shortURL(ByVal langeURL As String)
Dim retVal As String = ""
'Für dem API Aufruf wird benötigt:
'-> Die Versionsnummer (version)
'-> ein Benutzername (login)
'-> ein API-Schlüssel (apiKey)
'Den API-Aufruf starten:
Dim myRequest As WebRequest = WebRequest.Create _
("http://api.bit.ly/shorten?" & _
"version=2.0.1" & _
"&format=xml" & _
"&longUrl=" & langeURL & _
"&login=bitlyapidemo" & _
"&apiKey=R_0da49e0a9118ff35f52f629d2d71bf07")
Dim myResponse As WebResponse = myRequest.GetResponse
'Den erzeugen Strom auslesen
Dim myReader As StreamReader = _
New StreamReader(myResponse.GetResponseStream)
'Stream auslesen
retVal = myReader.ReadToEnd
myReader.Close()
Return retVal
End Function
Wie man sieht hat sich unser Code kaum verändert! Ich habe hier nur dem Link etwas angepasst, und um folgende Punkte erweitert:
- Version (Die Version der API, muss laut Doku mit angegeben werden!)
- Format (Gibt das Format an, das für die Antwort verwendet werden soll)
- Login (Der Benutzername von unserem Account)
- APIKey (Der API-Schlüssel, den wir erhalten haben)
- longURL (Und die zu kürzende URL)
Was hier wichtig ist, ist das Format. Hier hat man die Wahl zwischen XML und "json", wobei ich euch XML empfehlen würde, da es einfach übersichtlicher und einfacher verwendbar ist!
Wenn wir nun einen Request mit diesem langen Link erstellen erhalten wir auch eine Antwort im XML oder json Format:
Bild 1: Die zwei Rückgabetypen von bit.ly
Wie man sieht erhalten wir hier anders als bei tinyurl.com nicht direkt die kurze URL, sondern einen Haufen Informationen, wie Fehlercode, Fehlernachricht etc...
Uns interessiert aber natürlich nur die neue kurze URL, also müssen wir diese ersteinmal aus dem XML Durcheinander auslesen. Dazu habe ich diese Funktion erstellt:
Public Function extractURL(ByVal response As String)
'Ein XML-Dokument anhand der Antword von bit.ly erstellen:
Dim myDoc As New XmlDocument
myDoc.LoadXml(response)
'Nun nehmen wir uns das Element raus, in dem die
'neue kurze URL steht:
Return myDoc.SelectSingleNode("/bitly/results/nodeKeyVal/shortUrl").InnerText
End Function
Hier wird einfach nur ein XML-Dokument erzeugt (aus der Antwort) und dann der entsprechende Node ausgelesen!
Ein Hinweis noch: In der Doku wird weiterhin erwähnt, dass man nur ein bengenztes Kontingent an API-Aufrufen hat. Wenn man die API viel nutzen will sollte man sich bei bit.ly melden!
Auch hierzu habe ich ein Kleines Demoprogramm angefertigt:
Bild 2: Der uRL-Kürzer in Aktion
Download Hier: Download
Hat euch der Beitrag gefallen? Ich freu mich auf euer Feedback!
TreeView in XML speichern und zurück einlesen #2
Vor ca 2 Wochen habe ich eine Hilfsklasse zum Exportieren und Importieren von TreeNodes und XMLDateien veröffentlicht, mit dem Versprechen auf ein Update, mit dem das Exportieren ganzer TreeViews möglich ist.
Jetzt hatte ich Zeit und habe die Klasse um die entsprechenden Funktionen erweitert, sodass es nun möglich ist einen ganzen Baum in einer XML Datei abzulegen.
Warum habe ich das nicht gleich so gemacht? Ganz einfach weil ich das nicht brauchte!
Und es eigentlich sinnvoller finde die TreeNodes einzeln zu speichern!
Außerdem besteht beim Speichern einer TreeView ein großes Problem! Ansich eignet sich die Struktur einer TreeView perfekt um diese in einer XML Datei abzubilden. Nun kommt aber das Problem ins Spiel, dass eine TreeView mehrere "Kern" (root)-Äßte haben kann. Einer XML erlaubt das aber nicht. Eine XML Datei darf exakt eine Root-Node besitzen!
Wie umgeht man nun dieses Problem? Ich habe das so geregelt, dass ich einfach eine eigene Root-Node erstelle in die ich dann die Root-Nodes aus der TreeView einfüge die exportiert werden soll. Diese habe ich dementsprechend "rootNode" genannt! Also nicht erschrecken, wenn ihr in euren XML Files diese Fremde Node findet, diese wird beim Einlesen natürlich nicht mit eingelesen!
Ansonsten ähneld der neue Code sehr dem alten. Wie immer könnt ihr mir gerne Kommentare mit Bugs, Fehlern und Wünschen schreiben. Viel Spaß beim Testen und benutzen! Ich habe die Klasse wie auch letztes mal in ein Demoprojekt verpackt damit man die neuen Funktionen gleich live erleben kann! Wenn ihr nur auf die Klasse scharf seit, dann kopiert sie einfach aus dem Projektordner in euer eigenes Projekt!
Bei Weiteren Fragen schreibt mir bitte eine Mail!
Download: XMLParser v. 1.1
VB: TreeView in XML speichern und zurück einlesen
Als eine kleine Ergänzung zu der "Ordnerstrukturen einlesen" Serie möchte ich hier eine Möglichkeit zeigen, wie man TreeViews als XML Dateien serialisieren kann.
TreeViews sind ja nichts anderes als Ordner-Bäume. Diese Struktur eignet sich natürlich sehr für XML. Das .NET Framework bietet hier einige sehr bequeme Möglichkeiten um XML Dateien zu erzeugen, zu bearbeiten und einzulesen!
Um das zu demonstrieren habe ich eine VB.NET Klasse angefertigt, die diese Aufgaben für uns übernimmt, also das Abspeichern einer TreeView in einer XML Datei und auch das einlesen eines XML-Baums in eine TreeView.
Die Klasseheißt XMLParser und bietet zur Zeit genau 2 Funktionen nämlich zum Exportiren und Importieren von TreeNodes.
Ihr könnt diese Klasse sehr einach in euer eigenes Projekt Importiren und gleich loslegen! Dazu einfach im Projektmappen-Explorer auf euer Projekt rechtsklicken und über "Hinzufügen"->"Klasse" die XMLParser Klasse hinzufügen.
Ich habe die Anwendung möglichst einfach gehalten, sodass alle Aufrufe maximal eine Zeile in Anspruch nehmen:
Wie man sieht ist die Benutzung sehr einfach gehalten. Desweiteren kann man in dieser Version "nur" TreeNodes abspeichern, will man also eine Komplette TreeView abspeichern muss man mit eine Schleife alle Root-Nodes durchlaufen!
Natürlich können auch XML-Dateien eingelesen werden, die nicht vom XMLParser erzeugt wurden, wie zum Beispiel Config-Dateien oder "richtige" XML-Dateien!
Ich werde mit der Zeit die Funktionalität der Klasse erweitern, sodass auch ganze TreeViews gespeichert und eingelesen werden können. Und auch Merging (deu: Vereinigen) und Synchronisieren wird möglich sein!
Desweiteren werden ich weitere Überladungen einbauen, sodass die Funktionen weiterhin so übersichtlich sein werden!
Wenn ihr Interesse habt könnt ihr euch hier ein Demoprojekt inklusive der Klasse herunterladen.
Dieses Demoprojekt herunterladen: Download




