Meine Top 3 Entwickler-Tools

Ich habe zwar schon eine Xbox, allerdings ist die schon ein wenig in die Jahre gekommen. Außerdem finde ich das Thema dieser Blog-Parade sehr interessant. Hier nun meine Top 3 Entwickler-Tools

1) Jetbrains ReSharper
ReSharper ist für mich DAS Visual Studio Add-In, welches in nun seit mehreren Jahren benutze und eigentlich nicht mehr ohne kann.

2) Snippet-Compiler
Der Snippet-Compiler befindet sich ebenfalls seit mehreren Jahren auf meiner Festplatte. Häufig muss ich ein Stück Code testen und möchte dafür nicht extra Visual Studio starten müssen. Snippet-Compiler besetzt genau diese Lücke.

3) CodeSmith
Mit Hilfe von CodeSmith ist es möglich Code zu generieren, allerdings können die Templates selbst mit Logik gefüllt werden.  Damit hat mir CodeSmith schon viel, viel Arbeit erspart.

Visual Studio 2008: A selected drive is no longer valid

Für ein neues Projekt wollte ich heute Morgen die C++ Komponenten von Visual Studio 2008 Prof. nachinstallieren. Nach dem Aufrufen des Setups wurde jedoch folgende Fehlermeldung angezeigt:

A selected drive is no longer valid. Please review your installation path settings before continuing with setup.

Die Lösung habe ich in einem Thread im MSDN Forum gefunden. Nach der Deinstallation des SP1 für Visual Studio konnte die Nachinstallation durchgeführt und im Anschluss das SP1 erneut installiert werden.

Formulare mit ToolTip-Hilfen

Formulare sind etwas ganz Grundsätzliches jeder Web-Anwendung. Zu jedem guten Formular gehören Hilfe und Erklärungstexte, damit der Benutzer ganau weiß was er einzugeben hat. Meiner Auffassung nach sollte die Aufklärung im Vorfeld durchgeführt werden und nicht erst durch die Ausgabe einer entsprechenden Fehlermeldung – jedoch wäre ein langer Erklärungstext für jedes Feld zu umfangreich, und würde eher abschreckend wirken.

Die Lösung sind also ToolTips, die nach belieben des Benutzers eingeblendet werden. Häufig werden die Hilfetexte nicht vom Entwickler, sondern von anderen Kräften erstellt. Somit sollten die Hilfetexte leicht einzugeben ein und ohne Problem verändert werden können.

Die Verarbeitung und Anzeige der ToolTips überlasse ich der jQuery JavaScript Library mit der Abwandlung jTip, was bedeutet das diese Referenzen zunächst eingebunden werden müssen. Wichtig ist hierbei die Reihenfolge, die strikt eingehalten werden muss. Weiterhin gibt es eine CSS Datei, die sich um die nötigen Formatierungen kümmert.

<head runat="server">
    <link href="Stylesheet1.css" rel="stylesheet" type="text/css" />
    <script src="jquery.js" type="text/javascript"></script>
 
   <script src="jtip.js" type="text/javascript">

</script>
<title></title>
</head>

Die Hilfetexte selbst werden über einen generischen HttpHandler eingebunden, welcher wiederum den Zugriff auf eine globale Resource-Datei nutzt. Die Unterscheidung der Texte erfolgt über die Angabe eines Schlüssels, welcher in der gleichen Form in der Resource-Datei zu finden ist.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace FormularToolTip
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class HelpHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            string key = context.Request.QueryString["key"];
            context.Response.Write(String.Format("<p>{0}</p>",
                HttpContext.GetGlobalResourceObject("Help", key)));
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

Damit der jQuery Code die Arbeit aufnehmen kann, ist es nötig den Link zur Hilfe mit einer entsprechenden Klasse zu versehen. Über das Attribut Name, wird die Überschrift abgegeben.

Benutzername: <asp:textbox ID="Textbox1" runat="server"></asp:textbox>
<a href="HelpHandler.ashx?key=Help1" name="Benutzername" id="Help1" class="jTip">?</a>

Dieser Beispielcode zeigt den Link als Fragezeichen. Zusätzlich wird der Mauszeiger mit Hilfe der CSS Datei verändert, sobald er sich über dem Fragezeichen befindet, allerdings nur sofern der Browser dies unterstützt.

Das Ergebnis ist die Anzeige eines einfachen ToolTips, welcher dazu noch leicht einzugeben und zu warten ist. Leider ist auf dem Screenshot der Mauszeiger nicht zu sehen.

image   
Das Beispielprojekt gibt es hier zum Download.

Office (VSTO) Community Day in Wien

Mein Freund Lars Keller und Mario Meir-Huber veranstalten am 08.05.2009 in Wien einen Community Day rund um VSTO, also die Microsoft Office Entwicklung. Die Themenschwerpunkte des Tages sind:

- Einführung in die VSTO
- OpenXML: Das neue Office Format
- VSTO Deployment
- Sharepoint Workflows und Integration
- Interaktionen in der "Office-Welt" mit .NET
- Office plus Services

Mehr Informationen gibt es im Blog von Lars, oder unter
http://www.vsto-taskforce.de/wikis/ocd/hauptseite.aspx

Hash eines Passworts erstellen

Kaum eine Anwendung kommt heute noch ohne Passwort aus. Aufgrund dieser Tatsache verwenden Benutzer häufig einfache Passwörter, oder schlimmer noch – für jede Anwendung das gleiche Passwort. Umso wichtiger ist es das die Entwickler der Anwendung die Passwörter der Benutzer schützen, und das so gut wie möglich.

Damit Angreifer bei einer Komprimitierung der Datenbank nicht alle verwendeten Passwörter im Klartext vor sich haben, empfiehlt es sich ein Hash des Passworts zu erstellen und diesen in Verbindung mit einem Zufallswert (genannt Salt) in der Datenbank zu speichern.

Seit der Version 2.0 des .NET Frameworks steht die Klasse Rfc2898DerivedBytes zur Verfügung, welche auf dem Passwort-Hashing-Standard RFC2898 basiert.

Zunächst muss der Zufallswert (Salt) erstellt werden. In diesem Beispiel wird eine 16 byte lange Zufallszahl erstellt. Denkbar wäre jedoch auch eine Verwendung des Benutzernames, oder eines anderen eindeutigen Wertes.

byte[] GetSalt(int length)
{
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] buff = new byte[length];
    rng.GetBytes(buff);

    return buff;
}

In Verbindung mit dem Salt kann nun der Passwort Hash erstellt werden.

byte[] GetHashPassword(string password, byte[] salt)
{
    Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, salt, 10000);
    return rfc.GetBytes(16);
}

Die zurückgegeben Werte müssen, bevor Sie in der Datenbank gespeichert werden können, in einen Base64 String umgewandelt werden.

Bei der Anmeldung eines Users wird das eingegebene Passwort mit dem in der Datenbank gespeicherten Salt in einen Hash umgewandelt und mit dem Hash in der Datenbank verglichen. Bei Erfolg kann die Anmeldung fortgesetzt werden.

Das Beispielprojekt als Konsolenanwendung kann hier runtergeladen werden.

Einsatz auf der Cebit 2009

cebit

In diesem Jahr habe die die Gelegenheit bekommen vom 03.03 – 05.03 am Stand von Microsoft tätig zu sein. Zu finden bin ich am Community Stand in Halle 4 Stand A26. Ich freue mich auf viele bekannte Gesichter, viele Fragen und interessante Gespräche zum Thema .NET, Windows Vista und
Windows 7.

Visual Studio Team System Information Days

Auch dieses Jahr haben Interessierte wieder die Möglichkeit, sich bei der regelmäßig stattfindenden Workshop-Reihe "Visual Studio Team System Information Days" Einblick in die unterschiedlichen Rollen eines Entwicklungsprozesses und deren koordinierte Zusammenarbeit zu verschaffen.

Als ganzheitliches Toolset "aus eigener Hand" unterstützt Visual Studio Team System den gesamten Prozess des Application Lifecycle Management (ALM) von Anforderungsmanagement über Design, Entwicklung und Test bis hin zum Betrieb der Software.

Noch bis Ende Juni 2009 werden die kostenpflichtigen ganztägigen Workshops in verschiedenen deutschen Städten (in den Niederlassungen der Microsoft Deutschland GmbH) durchgeführt. Sie richten sich in erster Linie an Leiter der Anwendungsentwicklung, Projektleiter, Senior Developer sowie technische Entscheider aus Unternehmen mit Entwicklungsteams.

Für Community-Mitglieder entfällt die Teilnahmegebühr von 49,- EUR. Wie erfahrt Ihr auf der Veranstaltungswebseite:
http://go.microsoft.com/?linkid=9649599

Tracing mit ASP.NET AJAX

Die Verwendung von Tracing ist eine einfache und leichte Möglichkeit einem Fehler auf den Grund zu gehen oder einfach nur bestimmte Ereignisse und Vorgänge per Nachricht auszugeben. In der Code-Beside Datei einer ASP.NET Seite ist dies, je nach verwendeter Programmiersprache, einfach. Wird C# verwendet kann über die Klasse Trace und die Methode Write eine Nachricht ausgegeben werden.

In vielen Web Anwendungen wird jedoch JavaScript, häufig in Verbindung mit AJAX genutzt. Das ASP.NET AJAX Framework bietet allerdings auch eine Möglichkeit an Tracing zu verwenden.

Über die Funktion Sys.Debug.trace() kann eine einfache Meldung ausgegeben werden.

<script language="javascript" type="text/javascript">
    function TraceMessage()
    {
        Sys.Debug.trace("Tracing is working");
    }
</script>

Ist das Script-Debugging im Internet Explorer aktiviert und die Anwendung per Visual Studio ausgeführt, wird die Meldung im Visual Studio Output Window ausgegeben.

AJAXTracing

Eine weitere Möglich besteht in der Ausgabe in eine Textarea. Hier muss auf der Seite eine Textarea mit der ID TraceConsole eingefügt werden. Anschließend werden die Meldungen auch hier ausgegeben.

<textarea id="TraceConsole" cols="20" rows="20"></textarea>

Wird kann der Firefox Browser verwendet, können die Meldungen mit Hilfe des FireBug Add-Ons ebenfalls ausgegeben werden. Hierzu ist es nötig die Konsole für den localhost zu aktivieren.

AJAXTracingFirebug2

Dem dem sehr einfachen Ausgeben von Nachrichten bietet das AJAX Framework noch weit umfangreichere Möglichkeiten, um Fehler zu finden, oder das Verhalten der Anwendung zu beobachten. In der MSDN finden sich dazu mehrere Artikel und Beschreibungen:

Debugging and Tracing AJAX Applications Overview

Die Beispielanwendung kann hier runtergeladen werden.

Active Directory Authentifizierung mit C# via LDAP

Die Authentifizierung gegen ein Active Directory via LDAP ist mit wenigen Zeilen zu lösen. Nachdem Hinzufügen der Referenz System.DirecotryServices kann mit Angabe der Domäne, Benutzername und Passwort ein Aufruf mit Hilfe der Klasse DirecoryEntry gestartet werden.

static bool Authenticate(string domain, string username, string password)
{
    bool isAuthenticated = false;

    try
    {
        DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, username, password);
        object nativeObject = entry.NativeObject;
        isAuthenticated = true;
    }
    catch (DirectoryServicesCOMException) { }

    return isAuthenticated;
}

Das Beispielprojekt kann hier runtergeladen werden.

ASP.NET AJAX History Control

Ein häufiges Ärgernis von AJAX Anwendungen tritt dann zu Tage, wenn die Vor- und Zurück-Buttons des Browsers verwendet werden. Eine per AJAX ausgeführte Aktion wird vom Browser nicht als Seitenwechsel interpretiert und taucht somit auch nicht im Seitenverlauf auf. Im schlimmsten Fall landet der Benutzer der Seite also wieder am Beginn und hat alle getätigten Änderungen und Eingaben sind verloren.

Mit dem Service Pack 1 des .NET Framework 3.5 wurde der AJAX ScriptManager um eine neue Funktionalität erweitert. Diese neue Funktion setzt nach jedem AJAX Aufruf einen Verlaufspunkt im Browser, so dass die Vor- und Zurück-Buttons wieder verwendet werden können.  Das folgende Beispiel zeigt die Verwendung anhand einer DropDownListe und eines UpdatePanels auf. Nach dem Auswählen eines Eintrags wird der Bereich im UpdatePanel aktualisiert und die Auswahl in einem Label ausgegeben.

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>

<asp:UpdatePanel ID="updatePnl" runat="server">
    <ContentTemplate>
        <asp:DropDownList ID="ddlAuswahl" runat="server" OnSelectedIndexChanged="ddlAuswahl_SelectedIndexChanged" AutoPostBack="true">
            <asp:ListItem>Eintrag 1</asp:ListItem>
            <asp:ListItem>Eintrag 2</asp:ListItem>
            <asp:ListItem>Eintrag 3</asp:ListItem>
            <asp:ListItem>Eintrag 4</asp:ListItem>
            <asp:ListItem>Eintrag 5</asp:ListItem>
        </asp:DropDownList>
        <br />
        Auswahl: <asp:Label ID="lblAuswahl" runat="server" />
    </ContentTemplate>
</asp:UpdatePanel>

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void ddlAuswahl_SelectedIndexChanged(object sender, EventArgs e)
    {
        lblAuswahl.Text = ddlAuswahl.Text;
    }
}


Ohne die AJAX Funktionalität, die das UpdatePanel bereitstellt, wird nach jeder Auswahl die Seite neu geladen und somit auch der Zurück-Button im Browser aktiv. Sobald jedoch das UpdatePanel verwendet wird, bleibt der Button ausgegraut.

 HistoryIE0 

Neben dem setzen der Eigenschaft EnableHistory des ScriptManagers auf true, ist es weiterhin nötig einen HistoryPoint zu setzen. Dies wird im EventHandler der DropDownListe erledigt.

protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
    ScriptManager1.AddHistoryPoint("index", ddl.SelectedIndex.ToString(), "Point " + ddl.SelectedValue);
}

Um die gesetzten Werte später wieder abzurufen und – in diesem Beispiel – den richtigen Index der DropDownListe zu setzen, ist es nötig den Event OnNavigate des ScriptManagers zu abonnieren. An den EventHandler wird der Wert übergeben, welcher vorher mit Hilfe der Methode AddHistoryPoint gesetzt wurde.

protected void ScriptManager1_Navigate(object sender, HistoryEventArgs e)
{
    string selectedIndex = e.State["index"];

    if (String.IsNullOrEmpty(selectedIndex))
        ddl.SelectedIndex = 0;
    else
        ddl.SelectedIndex = Convert.ToInt32(selectedIndex);
}

Nach dem Starten der Anwendung ist das Ergebnis ein aktiviertes Zurück-Button im Browser.

HistoryIE1

Durch die flexible Struktur und die Events ist es möglich das Verhalten in komplexen AJAX-Anwendungen an die eigenen Bedürfnisse anzupassen.

Noch ein Hinweis:

Wird die Eigenschaft EnableHistory auf false gesetzt, ohne den Aufruf der Methode AddHistoryPoint() zu entfernen, wird der Aufruf mit einer Exception quittiert. Um dies zu verhindern kann die Eigenschaft zusätzlich noch im EventHandler abgefragt werden. Weiterhin gibt die Eigenschaft IsNavigating Auskunft darüber, ob momentan mit Hilfe des HistoryControls navigiert wird.

protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
    if (ScriptManager1.EnableHistory && ScriptManager1.IsNavigating == false)
    {
        ScriptManager1.AddHistoryPoint("index", ddl.SelectedIndex.ToString(), "Point " + ddl.SelectedValue);
    }
}

Das Beispielprojekt kann hier herruntergeladen werden.