Kategorie: .NET CF


.NET CF: XSL-Transformationen einsetzen

5. August 2009 - 22:55 Uhr

Das .NET CF ist eingeschränkt, das weiß man. Diese Einschränkungen betreffen leider auch so alltägliche Dinge, wie etwa LINQ to SQL (geht nicht) oder XSL-Transformationen (geht auch nicht). Stop, Moment, zumindest XSL-Transformationen gehen. Jedenfalls mit einem kleinen Trick.

Bei den meisten Windows Mobile-Geräten ab Version 6 (wenn nicht bei allen) befindet sich nämlich die MSXML-COM-Komponente auf den Maschinchen. Und diese Komponente kann angesprochen werden – nicht jedoch, ohne vorher die Komponente in das .NET CF-Projekt zu importieren. Leider geht das bei COM-Komponenten nicht direkt – aber es gibt den MIDL-Kompiler, der aus einer .idl-Datei eine .tlb-Datei zaubern kann, die sich wiederum als Referenz dem Projekt hinzufügen lässt.

Folgende Schritte müssen Sie ausführen, um MSXML zu verwenden:

  1. Öffnen Sie die Visual Studio-Eingabeaufforderung und wechseln Sie in das Verzeichnis [Programme]\Windows Mobile 6 SDK\PocketPC\Include\Armv4i
  2. Lassen Sie die tlb-Datei erstellen, indem Sie

    midl /L . msxml2.idl

    eingeben

  3. Kopieren Sie die erzeugte msxml2.tlb-Datei in das Verzeichnis Ihrer .NET CF-Applikation
  4. Fügen Sie die Datei Ihrem Projekt als Referenz über das "Durchsuchen"-Tab des Verweis-Dialogs hinzu

Nun können Sie mit Hilfe von MSXML auf die gute, alte, herkömmliche Art und Weise mit XML arbeiten:

// Quelle laden
DOMDocument doc = new DOMDocumentClass();
doc.load("source.xml");

// XSL-Stylesheet laden
DOMDocument xsl = new DOMDocumentClass();
xsl.load("style.xsl");

// Transformation durchführen
string html = doc.transformNode(xsl);

Na bitte, geht doch!

Kommentieren » | .NET CF, Tipp

#Mobile: HttpWebRequest erfolgreich durchführen

25. Juli 2009 - 22:43 Uhr

Das .NET Compact Framework – der kleine Bruder des "normalen" .NET-Frameworks – verfügt leider nicht über eine WebClient-Klasse. Stattdessen müssen Sie sich mit den auch vom WebClient verwendeten Klassen HttpWebRequest und HttpWebResponse "herumschlagen". Wobei dies im Grunde sehr einfach ist.

Angenommen, sie wollen das Versenden eines Formulars nachstellen, dann würden Sie folgenden Code verwenden können:

// Parameter werden als Name-Wert-Parameter übertragen
string parameters = "name=wert&name2=wert2";

// Request erzeugen
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://...");

// Pufferung aktivieren (.NETCF-spezifisch)
request.AllowWriteStreamBuffering = true;

// Zugriffsmethode definieren
request.Method = "POST";

// Inhaltslänge übertragen
request.ContentLength = parameters.Length;

Nachdem Sie so den WebRequest konfiguriert haben, müssen Sie die Daten übertragen. Sie können dies mit Hilfe der Stream-Implementierung erledigen, die Sie über die GetRequestStream()-Methode der WebRequest-Implementierung referenzieren können. Selbst und direkt in den Stream zu schreiben, wäre zwar möglich, aber wozu sich die Finger schmutzig machen, wenn Sie im System.IO-Namensraum bereits eine StreamWriter-Klasse haben, die die ganze Arbeit übernimmt?

// StreamWriter zum Schreiben verwenden
StreamWriter sw = new StreamWriter(request.GetRequestStream());

// Informationen übertragen
sw.Write(parameters);

// Daten senden
sw.Flush();

// StreamWriter schließen
sw.Close();

Wichtig ist in diesem Kontext, das Sie per .Flush() und .Close() das Senden der Daten und das Schließen des StreamWriters explizit vornehmen, da Ihnen ansonsten beim Abrufen der Daten eine ProtocolViolationException um die Ohren fliegt.

Nun können die Daten abgerufen werden. Dies geschieht mit Hilfe einer WebResponse-Implementierung, die sie über die Methode GetResponse() des WebRequests erreichen können. Diese WebResponse-Implementierung verfügt über eine Methode GetResponseStream(), die eine Stream-Implementierung zurück gibt, die es erlaubt, die Rückgabe des Servers abzurufen. Auch hier haben Sie die Wahl: Entweder das Rad neu erfinden, oder einen StreamReader verwenden:

// WebResponse-Implementierung abrufen
HttpWebResponse response = (HttpWebResponse) request.GetResponse();

// StreamReader zum Einlesen des HTMLs
StreamReader sr = new StreamReader(response.GetResponseStream());

// Rückgabe abrufen
string result = sr.ReadToEnd();

// Fertig
sr.Close();

Fertig. So richtig schwer war es eigentlich nicht. Um den Code noch besser nutzbar zu machen, empfiehlt es sich, ihn in einem Try-Catch-Block zu kapseln und die ggf. auftretenden Ausnahmen (keine Verbindung, falsche URL, sonstige Fehler) entsprechend abfangen zu lassen.

Kommentieren » | .NET CF, Mobile

#Mobile: Bug in IE6 Mobile / Webbrowser-Control beim .NET CF 3.5?

21. Juli 2009 - 12:41 Uhr

Entweder bin ich nicht in der Lage, mit dem Webbrowser-Control vom .NET CompactFramework umzugehen, oder es gibt da tatsächlich sowas wie einen Bug, wenn man es mit dem IE6 Mobile nutzen muss (was ja nicht in der Hand des Entwicklers liegt). Folgendes Szenario funktioniert bei mir schlicht nicht, wenn ich es mit einem IE6 Mobile im Emulator oder auch auf real existierenden Geräten (HTC Touch Pro2 beispielsweise) benutze:

Gegeben sei ein Formular mit einem darauf befindlichen Webbrowser-Control namens webBrowser1. Es gibt einen Eventhandler, der an das Navigating-Ereignis gebunden ist und nichts anderes machen soll, als die anzuspringende Adresse auszugeben:

private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
   MessageBox.Show(e.Url.ToString());
}

Beim Load-Ereignis des Formulars wird dem Webbrowser-Control über dessen .DocumentText-Eigenschaft ein einfacher HTML-Code zugewiesen:

private void Form1_Load(object sender, EventArgs e)
{
   string html =
      "<html><head><title>Sample</title></head><body><a href=\"http://www.microsoft.de\">Microsoft.de</a></body></html>";
   webBrowser1.DocumentText = html;
}

Auf einem Gerät mit dem (alten) IE4 gibt es zwei Anzeigen der MessageBox:

Windows Mobile 6 Professional Windows Mobile 6 Professional (2)

Wenn man es mit dem IE6 Mobile (etwa im Windows Mobile 6.5-Emulator) versucht, geschieht dies nicht – es wird nur die initiale MessageBox angezeigt:

WM 6.5 Professional - 240x400 WM 6.5 Professional - 240x400 (2)

Auch ein erneutes Binden des Ereignishandlers funktioniert nicht. Dabei – und das ist interessant – werden JavaScripts beispielsweise innerhalb der Webseite ausgeführt. Aber der Klick auf den Link führt zu keiner Reaktion – noch nicht einmal die referenzierte Webseite wird aufgerufen.

Bisher habe ich keinen Workaround darum gefunden. Ich weiß, dass das OpenCFFramework da was anbietet, aber ich sehe – wenn ich ehrlich bin – nicht wirklich ein, auf ein anderes Framework zu wechseln, wenn es sich doch um eine bereits in der Vergangenheit funktionierende Funktionalität handelt.

Nix da, ich nenne das einen Bug.

Kommentieren » | .NET, .NET CF, Mobile