Von der Datenbank bis zur Oberfläche mit .NET, Teil 3: Eine Weboberfläche mit ASP.NET

Know-how  –  5 Kommentare

In den ersten beiden Teilen des Tutorials entstanden Datenbank sowie Datenzugriffs-, Geschäftslogik- und Webserviceschicht. Die Webservices soll nun nicht nur – wie bisher – eine Konsolen-, sondern auch eine HTML-Weboberfläche konsumieren können.

Die Technik zum Erstellen von Webanwendungen mit dem .NET Framework heißt ASP.NET, wobei sie inzwischen nicht mehr nur als eine einzige Bibliothek anzusehen ist, da es mehrere Varianten von ASP.NET gibt. Im Rahmen des Tutorials sollen die sogenannten ASP.NET Webforms zum Einsatz kommen. Webforms sind der ursprüngliche und bislang deutlich verbreitetere Ansatz im Vergleich mit den neueren ASP.NET MVC, ASP.NET Dynamic Data und ASP.NET Webpages (vgl. Statistiken).

Von der Datenbank bis zur Oberfläche mit .NET

Um das Beispiel mitzuprogrammieren, benötigt der Entwickler Grundkenntnisse in der C#-Syntax und der Handhabung von Visual Studio 2010. Das Tutorial verwendet die englische Version von Visual Studio, weil es in der deutschen Ausgabe einen Fehler gibt, durch den sich das Beispiel nicht ohne viel manuelle Arbeit zum Laufen bringen lässt.

Selbst innerhalb der Webforms gibt es mehrere Wege zum Ziel, und das fällt schon beim Anlegen eines neuen Projekts auf: Der Entwickler hat die Wahl zwischen einer "Web Application" und einer "Website". Das zweite ist das neuere, hier verwendete Modell. Man erstelle eine Website aber nicht über Add | New Project, sondern über Add | New Website. Hierbei ist darauf zu achten, dass der Pfad im Dialog so gewählt wird, dass die Website-Dateien dann im gleichen Ordner wie die anderen Projekte der Projektmappe liegen. Websites haben anders als andere Visual-Studio-Projekte keine .csproj-Datei.

Die Website benötigt Referenzen auf die Webprojekte WWWings_ServiceProxies und WWWings_GO sowie die Systembibliothek System.ServiceModel. Außerdem muss der Entwickler die Dienst-Clientkonfiguration für die Webservices in die Website übernehmen. Dafür kopiert er das Element <system.serviceModel> aus der WWWings_ServiceProxies/app.config in die WWWings_Web/web.config-Datei. Wichtig ist, dass <system.serviceModel> direkt ein Unterelement von <configuration> sein muss. Aufzupassen ist darauf, dass man <system.serviceModel> nicht versehentlich in das vorhandene <system.web>-Element verschachtelt.

Zielarchitektur für diesen Teil des Tutorials (Abb. 1)

Für eine einheitliche Seitenstruktur über mehrere Seiten hinweg legt der Entwickler am besten zuerst eine Vorlagenseite an, indem er in der Website unter Add new Item die Vorlage "Master Page" wählt. Als Name sei hier WWWings.master vergeben. Eine .master- enthält die Grundstruktur einer HTML-Seite mit den Tags <html>, <head> und <body>. In den beiden ersten ist jeweils ein Platzhalter (<asp: ContentPlaceHolder>) eingebettet, der die von der Vorlagenseite abgeleiteten Seiten mit Inhalten befüllen kann. Listing 1 zeigt den möglichen Inhalt von WWWings.master. Es bindet eine Stylesheet- (wwwings.css) und eine Grafikdatei (WWWingsLogo.jpg) ein, deren Inhalt aber für die weitere Betrachtung nebensächlich ist. Die Dateien sind hier nicht wiedergegeben, aber natürlich via Download enthalten. Einen Platzhalter im Header benötigt man nicht; stattdessen gibt es einen Platzhalter für die Überschrift der Seite (C_Ueberschrift) und einen für den Inhalt (C_Inhalt). Die Vorlagenseite WWWings.master verfügt auch über eine sogenannte Code-Behind-Datei (WWWings.master.cs). Diese ist aber nicht anzupassen, da im vorliegenden Fall die Vorlagenseite keinen Programmcode benötigt.

Die ASP.NET-Buchungsmaske in Aktion (Abb. 2)

Abbildung 2 zeigt den Aufbau der Buchungsmaske. Es gibt drei Rahmen: den oberen für den Flug, den mittleren für den Passagier und den unteren für die Buchung. Für die Buchungsmaske legt der Entwickler eine Detailseite mit Namen Buchung.aspx an. Dazu wählt er Add new item und Web Form, wobei das Häkchen "Select master page" zu aktivieren ist. Dadurch kann er im nächsten Schritt WWWings.master als Vorlagenseite wählen. Der folgende Code zeigt die allgemeine Grundstruktur der Detailseite mit zwei Inhaltselementen entsprechend den Platzhaltern. Die Grundstruktur ist nun mit Inhalten zu füllen.

<%@ Page Title="" Language="C#" MasterPageFile="~/WWWings.master" 
AutoEventWireup="true" CodeFile="Buchung.aspx.cs" Inherits="Buchung" %>

<asp:Content ID="Content1" ContentPlaceHolderID="C_Ueberschrift"
Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="C_Inhalt" Runat="Server">
</asp:Content>

Listing 2 zeigt das fertige Layout der Detailseite. Die drei Bereiche werden durch <asp:Panel>-Elemente gebildet. Die Zahl-Eingabefelder und das Namenseingabefeld sind vom Typ <asp:TextBox>. Die Flughäfen kann der Entwickler mit einem Auswahlfeld bestimmen (<asp:DropDownList>), wobei die Auswahl "Alle" schon statisch in der ASPX-Seite als <asp:ListItem> vordefiniert ist. Die Liste der Flughäfen wird dann in der Code-Behind-Seite ergänzt – dafür sorgt AppendDataBoundItems="true". Die Schaltflächen erhält man über <asp:Button>. Für die tabellarische Ausgabe von Flügen und Passagieren kommt <asp:GridView> zum Einsatz. Im GridView-Steuerelement hinterlegt der Programmierer die auszugebenden Spalten. Die erste dient der Darstellung des Auswahl-Hyperlinks.

Bei den drei <asp:Button>-Steuerelementen findet der Entwickler erwartungsgemäß in OnClick="..." einen Verweis auf den auszuführenden Programmcode in der Hintergrundcodedatei. Aber auch <asp:TextBox> und <asp:DropDownList> verweisen mit OnTextChanged="..." und OnSelectedIndexChanged="..." die Bindung an Ereignisbehandlungsroutinen. Der Browser löst ja nach Eingabe in die Eingabefelder normalerweise keinen Postback zum Server aus, also das erneute Laden der gleichen Seite. ASP.NET sorgt aber durch den Zusatz AutoPostBack="True" dafür, dass der Browser entsprechenden JavaScript-Code erhält, der den Postback auslöst, sobald der Benutzer das Eingabefeld verlässt. Somit kann er komfortabel Suchvorgänge starten, ohne immer wieder auf die Suchen-Schaltflächen klicken zu müssen.