Warenkorb programmieren
ASP.NET-Shopping

DeveloperIT-ProjekteSoftware

Mit ASP.NET realisieren Profis unter Windows komfortable Web-Anwendungen. Internet Professionell zeigt Schritt für Schritt, wie Sie eine einfache Shop-Anwendung erstellen.

Darum geht es

Warenkorb programmieren

ASP.NET hat immer noch einen nur einstelligen Marktanteil. Das mag zum einen daran liegen, dass die Technologie noch relativ jung ist, ist zum anderen aber sicher auch im Marketing begründet. Bei dem ganzen Brimborium rund um »Service-orientierte Architektur« wird der Massenmarkt schlicht vergessen. Das ist eigentlich schade, denn mit ASP.NET ist es wirklich sehr einfach, schnell eine professionelle Web-Anwendung zu programmieren.

In diesem Artikel soll eine Warenkorbanwendung entwickelt werden, ein kleiner Online-Buchshop. Die Systemanforderungen sind dabei erfreulich niedrig. Windows XP Home Edition und ein paar Gratis-Programme, die Sie auf der Heft-CD finden, genügen. Besonders schnell und bequem gelingt die Umsetzung mit den Bordmitteln von ASP.NET Web Matrix.


Vorbereitungen

Warenkorb programmieren

Zunächst benötigen Sie eine Datenbank, in der Sie die Produkte ablegen. Doch keine Sorge, Sie müssen dafür nicht Access oder den Microsoft SQL Server kaufen oder die (kostenlose) Microsoft SQL Server Desktop Engine (MSDE) herunterladen Letzteres wäre unter www.asp.net/msde möglich. Nein, es ist sogar noch viel einfacher. Sie setzen eine Access-Datenbank ein, allerdings ohne Access zu verwenden. Auf dem Windows-System befinden sich nach der Installation der Microsoft Data Access Components (MDAC) die aktuellen Treiber, um unter anderem auch auf Datenbankquellen zuzugreifen. Diese Treiber ermöglichen es zusätzlich, auch Access-Datenbanken zu erstellen.

ASP.NET Web Matrix bietet hierfür eine GUI-Oberfläche. Auf der rechten Seite des Programms befindet sich das Workspace-Bedienfeld. Ein weiteres Register heißt Data. Ein Klick auf Add Database Connection erlaubt es, eine Verbindung zu einer Datenbank zu erstellen sowohl SQL Server/MSDE als auch Access. Der Punkt Create a new database legt eine neue Access-Datenbank an. Hier soll diese produkte.mdb heißen. Legen Sie sie der Einfachheit halber in dasselbe Verzeichnis, in dem alle anderen Beispieldateien abgelegt werden. Das ist normalerweise aus Sicherheitsgründen keine gute Idee, reicht aber zu Demonstrationszwecken aus. Legen Sie dann zwei Tabellen an. Zunächst kategorien, die eine Liste aller Buchkategorien enthält. Dazu benötigen Sie die folgenden Felder:

id Datentyp AutoNumber, Primärschlüssel (IsPrimaryKey = True)
name Datentyp Text, 50 Zeichen

Zu Testzwecken legen Sie zwei Kategorien an, deutsche Bücher und englische Bücher. Auf Grund des AutoNumber-Datentyps haben diese die ID 1 und 2. Sie benötigen diese Daten als Fremdschlüssel in der zweiten Tabelle, produkte. Dort liegen alle Produkte. Sie benötigen die folgenden Felder:

id Datentyp AutoNumber, Primärschlüssel
kategorie_id Datentyp Integer
name Datentyp Text, 50 Zeichen
beschreibung Datentyp Text, 255 Zeichen
preis Datentyp Currency

Füllen Sie diese Tabelle mit Buchdaten. Achten Sie beim Feld kategorie_id darauf, dass Sie den richtigen Wert für die zugehörige Kategorie eintragen.


Kategorien

Warenkorb programmieren

Auf der ersten Seite sollen zunächst alle Kategorien ausgegeben werden. Dazu ist eine Datenbankabfrage notwendig, die mit Web Matrix? Code Wizards
und halbautomatisch erzeugtem Code schnell gebaut ist. Sie finden die Wizards im linken Bedienfeld von ASP.NET Web Matrix. Legen Sie eine neue ASP.NET-Seite an (Sprache: C#) und wählen Sie dann in der Code-Ansicht den Assistenten SELECT Data Method. Dann geben Sie die Datenbankverbindung an (die zuvor angelegte produkte.mdb), wählen die Tabelle kategorien und dort alle Felder (*) aus und geben an, dass die Methode (nennen Sie sie Kategorien) einen DataReader zurückliefern soll.

Eine kleine Modifikation befindet sich in diesem Code: Es wird nicht der absolute Pfad zur MDB-Datei angegeben, sondern der virtuelle ? das erledigt der Aufruf von Server.MapPath().

Die Methode Kategorieliste() ruft diesen DataReader ab, durchläuft ihn und wandelt das Ergebnis in HTML um. Dazu werden die Inhalte als zweispaltige Tabelle ausgegeben. Jeder Eintrag in der Kategorieliste wird mit dem URL kategorien.aspx?id= verlinkt. Nun benötigen Sie in der ASP.NET-Seite nur ein div-Element zur Ausgabe:


Produkte

Warenkorb programmieren

Es muss also auch möglich sein, in der Seite kategorien.aspx alle Produkte einer Kategoriegruppe anzuzeigen. Das geht allerdings ganz analog zur Ausgabe der Kategorieliste: Sie erstellen per Code Wizard eine Methode Artikel(), die alle Artikel einer Artikelgruppe zurückliefert. Dazu müssen Sie im Assistenten eine WHERE-Bedingung angeben, das Feld kategorie_id muss dabei identisch zu einem Filter @kategorie_id sein. Der Code Wizard erstellt dann die Methode Artikel() so, dass die gewünschte Kategorienummer als Parameter übergeben wird. Die selbst geschriebene Methode Artikelliste() ruft Artikel() auf und gibt alle Produkte der Kategorie ebenfalls tabellarisch aus. Jedes Produkt ist mit dem URL artikel.aspx?id= verlinkt.

Jetzt müssen Sie nur noch festlegen, was passieren soll, also ob die Kategorieliste oder die Artikelliste angezeigt werden soll. Das kann aber einfach entschieden werden: Wenn kategorien.aspx ohne URL-Parameter aufgerufen wird, wird die Kategorieliste ausgegeben, ansonsten die Artikelliste. Der folgende Code sorgt dafür:

void Page_Load() {
int id;
if (Request.QueryString["id"] != null) {
try {
id = Convert.ToInt32(Request.QueryString["id"]);
Artikelliste(id);
} catch (Exception ex) {
}
} else {
Kategorieliste();
}
}


Produktdetails

Warenkorb programmieren


Kontrolle

Warenkorb programmieren

Natürlich soll der Benutzer nicht Müll in das Textfeld einfügen dürfen, sondern nur Zahlen. Dazu benötigen Sie zwei Validation-Controls von ASP.NET: Den CompareValidator, um den Datentyp zu überprüfen, sowie den RequiredFieldValidator, der prüft, ob überhaupt etwas im Feld steht:


ControlToValidate="Anzahl" ErrorMessage="*"
Operator="DataTypeCheck" Type="Integer"
Display="Dynamic" />

ControlToValidate="Anzahl" ErrorMessage="*"
Display="Dynamic" />

Um das Control zu steuern, benötigen Sie ein Attribut, in dem die ID des Artikels angegeben wird. Die Eigenschaft heißt ProduktId (id ist ja schon vergeben), wird aber innerhalb des Steuerelements in einer Variablen id gespeichert:

private int id;

public int ProduktId {
set {
try {
id = Convert.ToInt32(value);
} catch (Exception ex) {
id = 0;
}
}
get {
return id;
}
}


Verbindung zur Datenbank

Warenkorb programmieren

Es fehlt noch die Verbindung zur Datenbank. Schließlich müssen die Produktdaten ja irgendwo herkommen. Auch hier ist Web Matrix wieder sehr nützlich und generiert mit dem Assistenten SELECT Data Method den Code, um Informationen über ein bestimmtes Produkt als DataReader zurückzuliefern. Nennen Sie die Methode Produktinfos(). In der Methode Page_Load() werden die Daten ausgelesen und in die zuvor dafür eingerichteten Web-Controls eingefügt:

void Page_Load() {
System.Data.IDataReader idr = Produktinfos(id);
if (idr.Read()) {
Name.Text = idr["name"].ToString();
Beschreibung.Text = idr["beschreibung"].ToString();
Preis.Text = String.Format("{0:c}", Convert.ToDouble(idr["preis"]));
}
}

Das Anzeigen des User-Controls geschieht in der Datei artikel.aspx. Dort befindet sich nur das nackte User-Control:

<%@ Page Language="C#" %>
<%@ Register TagPrefix="IPro" TagName="Produkt" Src="artikel.ascx" %>



Der übergebene URL-Parameter mit der Produkt-ID wird ausgelesen und an das eingefügte User-Control übergeben, so dass die korrekten Artikelinfos angezeigt werden:


Warenkorb

Warenkorb programmieren

Bei einem Klick auf die Schaltfläche müssen die Waren in den Warenkorb gelegt werden. Da das gesamte Produktangebot datenbankgestützt ist, geht das recht einfach. Alle Warenkorbdaten werden in einer Session-Variablen gespeichert.

Dabei kommt der ASP.NET-Datentyp Hashtable zum Tragen, eine fortgeschrittene Version eines assoziativen Arrays. Das ermöglicht später einmal eine Erweiterung des Warenkorbs, denn in einem solchen Array können auch unterschiedliche Datentypen abgelegt werden. In diesem Beispiel ist das nicht der Fall.

Der Schlüssel für jedes Element in der Hashtable ist die Produkt-ID, der Wert ist die Anzahl der Elemente. Zunächst prüfen Sie beim Klick auf die Schaltfläche, ob der Benutzer eine »ordentliche« Stückzahl angegeben hat. Zwar funktionieren die ASP.NET Validation-Controls auch auf Seiten des Clients, aber nur im Internet Explorer und nur mit aktiviertem Javascript ? zwei Dinge, die Sie leicht abschaffen können.

void Einfuegen(Object o, EventArgs e) {
Page.Validate();
if (!Page.IsValid) {
return;
}

Dann lesen Sie die aktuelle Hashtable aus der Session aus oder legen Sie neu an, falls noch nichts im Warenkorb liegt:

Hashtable ht;
if (Session["warenkorb"] != null) {
ht = (Hashtable)Session["warenkorb"];
} else {
ht = new Hashtable();
}


Artikel einfügen

Warenkorb programmieren

Jetzt wird der Artikel in den Warenkorb eingefügt. Zunächst wird nachgesehen, ob der Artikel schon vorhanden ist ? es kann ja sein, dass ein Kunde so begeistert ist, dass er einen Artikel mehrfach in den Einkaufskorb legt. In diesem Fall wird die Anzahl des Artikels erhöht, ansonsten wird ein neuer Eintrag in der Hashtable angelegt:

if (ht.ContainsKey(id)) {
int anzahl = Convert.ToInt32(ht[id]);
anzahl += Convert.ToInt32(Anzahl.Text);
ht[id] = anzahl;
} else {
ht.Add(id, Convert.ToInt32(Anzahl.Text));
}
Session["warenkorb"] = ht;
Ausgabe.Text = "Artikel eingefügt.";
}


Datenausgabe

Warenkorb programmieren

Diese Daten müssen auf der Warenkorbseite warenkorb.aspx noch hübsch ausgegeben werden. Auch hier wäre es natürlich möglich, die HTML-Tabelle schrittweise aufzubauen. Sie gehen jedoch einen anderen Weg: Es gibt auch ASP.NET-Web-Controls für Tabellen. Damit bauen Sie die Warenkorbausgabe objektorientiert auf. Zunächst etwas Markup, das Grundgerüst:











In der Methode Page_Load() der Seite wird die Tabelle dann mit Daten erweitert. Hier ein Ausschnitt:

c1 = new TableCell();
c1.Text = anzahl.ToString();
c2 = new TableCell();
c2.Text = name;
c3 = new TableCell();
c3.Text = String.Format("{0:c}", preis);
c4 = new TableCell();
c4.Text = String.Format("{0:c}", anzahl * preis);
r = new TableRow();
r.Cells.Add(c1);
r.Cells.Add(c2);
r.Cells.Add(c3);
r.Cells.Add(c4);
Warenkorb.Rows.Add(r);


Erweiterungen

Warenkorb programmieren

Starten Sie mit [F5] den Code. Web Matrix bietet an, den integrierten ASP.NET-Webserver zu benutzen. Dieser kann zwar nur für den lokalen Zugriff verwendet werden, ist aber zum Testen ausreichend.

Das ist natürlich erst der erste Schritt. Viele Erweiterungen sind denkbar. So könnten Sie die Produkte auch noch mit aussagekräftigen Grafiken bewerben, deren URLs Sie in der Datenbank ablegen. Außerdem muss die Bestellung noch per E-Mail an den Webmaster des Shops verschickt werden.


Sessions ohne Cookies

Warenkorb programmieren

Dieser Warenkorb speichert die Session-Informationen in einem temporären Cookie. Das können Sie aber ändern.

Legen Sie dazu im Hauptverzeichnis der Web-Anwendung bei der Verwendung des Web-Matrix-Webservers eine Datei web.config mit folgendem Inhalt an:





Dann fügt ASP.NET bei jedem Aufruf in den URL ein nicht existierendes Verzeichnis ein ? die Session-ID in Klammern. Doch obwohl es den Ordner nicht gibt, versteht der Webserver die Anforderung richtig, extrahiert die Session-ID aus dem URL und kann so auch ohne Cookies auf die Session-Daten zugreifen.

Alle Listings zum Workshop finden Sie auf der Heft-CD und unter listings.internet-pro.de.