Saschas Weblog

ESCde Developer Blog

  Home :: Kontakt :: RSS Feed
  30 Posts :: 0 Artikel :: 10 Kommentare :: 32 Trackbacks

Archiv

Post Kategorien

ESCde

ESCde Blogger

Sonntag, 29. Juli 2007 #

Mit der Copy() Methode lässt sich eine DataTable als Ganzes kopieren, komplett mit Schema und Daten.

Für einzelne DataRows kann man eine Kombination aus der Clone() und ImportRow() Methode verwenden.

private DataTable CopyFourRows(DataTable dt)
{
    // mit Clone Methode Tabellenstruktur kopieren
    // Schema, ohne Daten
    DataTable dt_copy = dt.Clone();

    // mit ImportRow Methode die ersten 4 Zeilen kopieren
    for (int i = 0; i <= 4; ++i)
    {
        dt_copy.ImportRow(dt.Rows[i]);
    }

    return dt_copy;
}

Um binäre Dateien, wie etwa Bilder, über einen Webservice zu senden oder empfangen, kann man sie in ein ByteArray konvertieren.

public byte[] createByteArray(string imageName) 
{
   FileInfo fileInfo = new FileInfo(imageName);
   FileStream fileStream = fileInfo.OpenRead();
   byte[] byteArray = new byte[fileStream.Length];        
   int bytesRead = fileStream.Read(byteArray, 0, fileStream.Length);
   Console.WriteLine("{0} bytes have been read from {1}", 
   bytesRead.ToString(), imageName);
   return byteArray;
}

In die andere Richtung:

public void saveAsImage(byte[] bytes, string imageName) 
{
   MemoryStream memStream = new MemoryStream(bytes);
   System.Drawing.Image image = 
   System.Drawing.Image.FromStream(memStream);
   image.Save(imageName);
   Console.WriteLine("{0} was created successfully.", imageName);
}

Freitag, 06. Juli 2007 #

Unter [1] gibt es eine Übersicht aller vordefinierten Tastatur Shortcuts für Windows Vista.
Interessant fand ich

  • Windows-Taste + Leertaste
    Bringt die Gadget-Sidebar in den Vordergrund
  • Windows-Taste + Zahl
    Startet das entsprechende Symbol in der Schnellstart-Symbolleiste, also Windows-Taste + 3 startet hier den Internet Explorer.
  • Strg + Mausrad im Dateibereich des Windows-Explorers (rechte Seite)
    ändert die Ansicht (Details, Liste, kleine Symbole, ...).
    Äußerst praktisch, da ich es meinem Explorer nicht abgewöhnen kann, immer wieder mal in die Ansicht große Symbole umzuschalten.

 

[1] Windows Vista Help: Keyboard shortcuts,
http://windowshelp.microsoft.com/Windows/en-US/help/2503b91d-d780-4c80-8f08-2f48878dc5661033.mspx


Donnerstag, 05. Juli 2007 #

Der Zugriff auf Exceldateien unter .Net 2.0 ist dank ADO.Net erstaunlich einfach. Dazu wird der OleDbProvider verwendet.

string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;
    Data Source=D:\Excel\Workbook.xls;Extended Properties=""Excel 8.0;HDR=YES;""";

Dieser ConnectionString enthält den Speicherort der Datei und gibt an, dass die erste Zeile der Worksheets die Spaltennamen enthält.

Nachdem die Connection geöffnet ist, verhält sich alles, wie von ADO.Net gewohnt.
Mit Hilfe der GetSchema() Methode lassen sich Informationen zu den vorhandenen Tabellen (gleich Worksheets) und Spalten abrufen.

using (OleDbConnection connection = new OleDbConnection(connectionString))
{
    connection.Open();

    DataTable tables = connection.GetSchema("Tables");
    DataTable columns = connection.GetSchema("Columns");
}

In den nachfolgenden Screenshots sieht man die jeweilige DataTable mit den Schemainformationen im DataSet-Visualizer des Visual Studio Debuggers. Achtung: Excel hängt für den Tabellenname ein $ an den Namen des Worksheets. Hier: Worksheetname "Studenten" wird zu Tabelle "Studenten$".

Select-Abfragen funktionieren auch mit Parameter und das Ergebnis lässt sich an Steuerelemente binden.

OleDbCommand selectCommand = new OleDbCommand(
    "SELECT [MatrikelNr], [Vorname], [Nachname] FROM [Studenten$] " +
    "WHERE [Nachname] LIKE @Nachname", 
    connection);
selectCommand.Parameters.AddWithValue("Nachname", "A%");

OleDbDataAdapter adapter = new OleDbDataAdapter(selectCommand);

DataTable studenten = new DataTable();
adapter.Fill(studenten);

this.GridView1.DataSource = studenten;
this.GridView1.DataBind();

Auch die Insert- und Update-Commands funktionieren wie erwartet:

OleDbCommand insertCommand = new OleDbCommand(
    "INSERT INTO [Studenten$] ([MatrikelNr], [Vorname], [Nachname]) " +  
    "VALUES (@MatrikelNR, @Vorname, @Nachname)",
    connection);
insertCommand.Parameters.AddWithValue("MatrikelNr", "123459");
insertCommand.Parameters.AddWithValue("Vorname", "Bert");
insertCommand.Parameters.AddWithValue("Nachname", "Becker");
int rowsAffected = insertCommand.ExecuteNonQuery();

 

 

 


Montag, 02. Juli 2007 #

Das hat mich einige Zeit gekostet: per Code eine OleDbConnection zu einer Access Datenbank zu öffnen, die im ConnectionStrings-Abschnitt der web.config Datei mit einem relativen Pfad konfiguriert ist.

Während das AccessDataSource Control in der DataFile-Eigenschaft eine relative Pfadangabe wie

DataFile="~/App_Data/datenbank.mdb" 

richtig umzusetzen weiß, funktioniert das  nicht mir einer Connection, die in der web.config konfiguriert ist. Obwohl "DataSource=<absoluter Datenbankpfad>" einwandfrei funktioniert, brachten weder

<connectionStrings>
    <add name="DatenbankConnectionString" 
        connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
        DataSource=~App_Data/datenbank.mdb"
        providerName="System.Data.OleDb"/>
</connectionStrings>

noch folgende Variationen des ConnectionStrings den gewünschten Erfolg:

connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
    Data File=~App_Data/datenbank.mdb"
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
    DataFile=~App_Data/datenbank.mdb"

Die Lösung:

"~App_Data/" muss im ConnectionString der web.config Datei durch "|DataDirectory|" ersetzt werden.

<connectionStrings>
  <add name="DatenbankConnectionString" 
    connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
    Data Source=|DataDirectory|datenbank.mdb" 
    providerName="System.Data.OleDb"/>
</connectionStrings>

Dann lässt sich eine OleDbConnection im Code mit

OleDbConnection db = new OleDbConnection(
    ConfigurationManager.ConnectionStrings["DatenbankConnectionString"].ConnectionString);
db.Open();

wie gewünscht öffnen.

Das gleiche gilt auch für Verbindungen zu SQLExpress-Datenbanken.


Um ein System.Drawing.Color-Objekt aus einem String mit einem hexadezimalen Farbcode zu erzeugen, muss man den System.Web.UI.WebControls.WebColorConverter verwenden. Ein direktes Erzeugen mit Hilfe des HexCodes im Konstruktor einer neuen Color-Instanz ist nicht möglich.

string hexColor = "#FF8080";
System.Web.UI.WebControls.WebColorConverter converter = 
    new WebColorConverter();
System.Drawing.Color color = 
    (System.Drawing.Color)converter.ConvertFrom(hexColor);
e.Cell.BackColor = color;

 


Mittwoch, 13. Juni 2007 #

Von Manning Publications ist im Februar das Buch Windows PowerShell in Action von Bruce Payette erschienen, das ich durchaus lesenswert fand.

Unter [1] gibt es jetzt Probekapitel zum kostenfreien Download. Kapitel 1 gibt einen Einstieg in Windows Powershell. Anhang C erklärt die anfänglich etwas gewöhnungsbedürftige Grammatik von Powershell.

[1] Windows PowerShell in Action, http://www.manning.com/payette/


Mittwoch, 09. Mai 2007 #

Wer mit Visual Studio 2003 gearbeitet hat und die Vorzüge des Entwickelns unter Visual Studio 2005 einmal kennen gelernt hat, möchte eigentlich nicht mehr zurück. Trotzdem gibt es immer noch Projekte, die auf dem .Net Framework 1.1 laufen müssen. Ein Powertoy für Visual Studio 2005 hilft aus diesem Dilemma: MSBee. MSBee ist eine Erweiterung für MSBuild und steht für MSBuild Everett Environment. Everett war der Codename für das .NET Framework 1.1. Mit MSBee kann der Entwickler in Visual Studio 2005 entwickeln und das Projekt dann mit dem .Net Framework 1.1 kompilieren. Das funktioniert soweit auch ganz gut, solange man Codebibliotheken entwickelt. Für Windows Forms oder Asp.Net Seiten können die Visual Studio 2005 Designer nicht verwendet werden, weil diese die Steuerelemente für .Net 2.0 verwenden. Alle anderen Namensräume von .Net 2.0 können natürlich ebenfalls nicht verwendet werden, genauso wie z.B. partielle Klassen oder Generics, die ebenfalls unter .Net 1.1 noch nicht zur Verfügung standen. Auch die Intellisense von Visual Studio 2005 und die Hilfe passen sich nicht an .Net 1.1 an. 

Installationsvoraussetzungen für MSBee:

Um nach der Installation nun ein Projekt in Visual Studio 2005 zum Kompilieren mit dem .Net Framework 1.1 zu konfigurieren, müssen zunächst die MSBee .target Dateien in das Projekt geladen werden. Dazu sind folgende Schritte notwendig:

  • Das Projekt wie gewohnt erstellen, speichern und wieder schließen. 
  • Anschließend die Projektdatei (.csproj / .vbproj) in Notepad öffnen.

Bei einem C# Projekt:

  • folgende Zeile kurz vor Dateiende in der .csproj-Datei suchen:
    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> 
  • Unmittelbar unter dieser Zeile muss folgende Zeile eingefügt werden: 
    <Import Project="$(MSBuildExtensionsPath)\MSBee\MSBuildExtras.FX1_1.CSharp.targets" />

Bei einem Visual Basic Projekt:

  • folgende Zeile kurz vor Dateiende der .vbproj-Datei suchen:
    <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
  • Unmittelbar unter dieser Zeile muss folgende Zeile eingefügt werden: 
    <Import Project="$(MSBuildExtensionsPath)\MSBee\MSBuildExtras.FX1_1.VisualBasic.targets" />

Wenn das Projekt in Visual Studio wieder geöffnet ist, müssen in den Buildeinstellungen der Projekteigenschaften die Conditional compilation symbols den Wert FX1_1 besitzen.

Nun kann das Projekt kompiliert werden. Dabei wird die .Net Framework Version 1.1 verwendet.

Das Ergebnis kann man überprüfen, indem man die erzeugte DLL mit dem Microsoft .Net Framework IL-Disassembler öffnet (Start / All Programs / Microsoft .NET Framework SDK v2.0 / SDK Command Prompt / Ildasm)

Dort sieht man im Manifest der dll-Datei die Framework-Version, mit der die Datei kompiliert wurde.

 

[1]  MSBee, < 1 MB, http://www.microsoft.com/downloads/details.aspx?FamilyID=e0d0776f-25c4-444a-a6b9-71d06826f5b4&displaylang=en
[2] .Net Framework 1.1 Redistributable (Runtime), 24 MB, http://www.microsoft.com/downloads/details.aspx?familyid=262D25E3-F589-4842-8157-034D1E7CF3A3&displaylang=en
[3] .Net Framework 1.1 SDK, 106 MB, http://www.microsoft.com/downloads/details.aspx?familyid=9B3A2CA6-3647-4070-9F41-A333C6B9181D&displaylang=en


Donnerstag, 12. April 2007 #

Nicht immer hat man für die Entwicklungsumgebung ein Serverzertifikat zur Hand, mit dem sich eine SSL-verschlüsselte Website testen lässt. Mit SelfSSL aus den Internet Information Services (IIS) 6.0 Resource Kit Tools hat man sich schnell selbst ein Zertifikat erstellt und in IIS importiert. Nach der Installation der Resource Kit Tools auf dem Webserver, lässt sich SelfSSL über das Startmenü aufrufen. Genauer gesagt, wird eine Kommandozeile mit einem Hilfetext geöffnet.

Die Standardeinstellungen sind ausreichend, also das Tool mit selfSSL aufrufen, die Nachfrage für die Installation des Zertifikats in der Standardwebsite des IIS bestätigen. - Das war's. Im Webbrowser kann die Installation mit https://<computername> überprüft werden.

Da wir uns das Zertifikat selbst ausgestellt haben, werden alle gängigen Webbrowser eine Warnmeldung ausgeben. Die Funktionalität wird durch diese Meldung aber nicht beeinträchtigt. Selbst ausgestellte Zertifikate sollten aber nur in der Testumgebung verwendet werden.


Samstag, 03. März 2007 #

Die MemoryStream-Klasse erstellt Streams, die im Arbeitsspeicher gesichert werden statt zum Beispiel im Dateisystem, wie das bei FileStreams der Fall ist. Eine Anwendung, die bisher viel mit temporären Dateien im Filesystem arbeitet, kann u. U. eine Menge Performance gewinnen, indem sie stattdessen MemoryStreams verwendet. Viele Komponenten, wie z. B. das RichTextBox-Steuerelement, akzeptieren nämlich in ihren Load() und Save() Methoden nicht nur einen Dateinamen, sondern wahlweise auch eine Stream-Instanz. Und hier kann statt einem FileStream auch ein MemoryStream übergeben werden. Das Beispiel hier zeigt die Verwendung eines MemoryStreams mit einem RichTextBox-Steuerelement.

1 string _rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1031{" + 2 @"\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;" + 3 @"}}\viewkind4\uc1\pard\f0\fs17 Hallo Stream\par}"; 4 5 // *** RTF-Datei aus Speicher laden *** 6 // Stream-Objekt als MemoryStream-Objekt erstellen 7 // Byte-Array Darstellung von String im Konstruktor übergeben 8 Stream s = new MemoryStream(UTF8Encoding.Default.GetBytes(_rtf)); 9 //Stream an LoadFile() Methode übergeben 10 this.richTextBox1.LoadFile(s, RichTextBoxStreamType.RichText); 11 12 // *** RTF-Datei in Speicher sichern *** 13 s = new MemoryStream(); 14 // Stream an SaveFile() Methode übergeben 15 this.richTextBox1.SaveFile(s, RichTextBoxStreamType.RichText); 16 // Stream in MemoryStream casten, damit ToArray() Methode 17 // aufgerufen werden kann 18 MemoryStream m = (MemoryStream)s; 19 byte[] b = m.ToArray(); 20 // Byte-Array in String zurückkonvertieren 21 string t = UTF8Encoding.Default.GetString(b); 22 //ASCIIEncoding.Default.GetString 23 m.Dispose(); 24 s.Dispose();

Beim Umwandeln von/ in Byte-Arrays helfen die statischen Methoden der jeweiligen Encoder-Klasse. Um ein ASCII-codiertes Byte-Array zu erstellen, hätte in Zeile 8 die Methode ASCIIEncoding.Default.GetBytes() aufgerufen werden müssen.