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

Benutzeroberfläche "advanced"

Eingabemaske für neue Passagiere

Nun soll die Benutzeroberfläche noch etwas weiter getrieben werden, um zu zeigen, wie man Daten zwischen Webseiten austauscht und die Operation SavePassagiere() verwendet. Abbildung 4 zeigt die Eingabemaske für neue Passagiere, die man über die Schaltfläche "Neuer Passagier" aus der Buchung.aspx erreicht.

NeuerPassagier.aspx (Abb. 4)

Der Entwickler muss zunächst in WWWings_Web ein weiteres Element vom Typ "Web Form" mit Namen NeuerPassagier.aspx und Bezug auf die Vorlagenseite WWWings.master anlegen. Den Inhalt dieser .ASPX-Seite zeigt Listing 5. Einiges, aber nicht alles davon kann der Programmierer in Visual Studio auch im Designer gestalten. Die Eingabemaske für die neuen Passagiere könnte er manuell aus einzelnen TextBox-Steuerelementen aufbauen. Hier sei aber als Grundgerüst das DetailsView-Steuerelement verwendet. Mit dem Zusatz DefaultMode="Insert" präsentiert es sich direkt beim Aufruf als leeres Eingabeformular. Die einzelnen darzustellenden Eingabefelder sind in <Fields> definiert. Zur einfachen Darstellung eines Texteingabefeldes würde <asp:BoundField> reichen. Da hier aber die Eingabe mit Validatoren geprüft werden soll, sind <asp:TemplateField>-Elemente notwendig, die etwas mehr Arbeit machen, weil man in ihnen das Aussehen der Zeilen sowohl für die Darstellung als auch die Eingabe explizit definieren muss.

Name und Vorname werden durch <asp:RequiredFieldValidator> zum Pflichtfeld. Die Prüfung dessen erfolgt clientseitig durch JavaScript und dann zur Sicherheit noch einmal serverseitig. Das JavaScript muss man aber nicht selbst schreiben, da ASP.NET es erzeugt. Das Geburtsdatum ist im Objektmodell kein Pflichtfeld (vgl. Teil 1 des Tutorials), aber es soll hier mit <asp:RegularExpressionValidator> ein gültiges Datum geprüft werden. Der hinterlegte reguläre Ausdruck kontrolliert aber nur, ob der grundsätzliche Aufbau korrekt ist. Eine Datumseingabe wie 99.12.2012 würde nicht bemängelt. Auch <asp:RegularExpressionValidator> verrichtet die Arbeit via JavaScript und serverseitig. Beim Passagierstatus gibt es ein Auswahlfeld; hier ist eine Fehleingabe also ausgeschlossen. Die letzte Zeile aktiviert mit <asp:CommandField> die Links zum Speichern und Abbrechen.

Es fehlt nun noch die komplette Zusammenarbeit mit dem Webservice. Diese hinterlegt der Entwickler im einfachsten Fall nicht in der Hintergrund-Code-, sondern in einer getrennten C#-Klassendatei im Webprojekt. Wenn er ein Element vom Typ "Class" einfügt, weist Visual Studio darauf hin, dass in einer ASP.NET-Website alle freien Klassendateien im Unterordner App_Code liegen müssen, und legt diesen dann an. Die Klasse NeuerPassagierManager realisiert zwei Methoden: Laden() erzeugt eine Instanz von Passagier und Einfuegen() speichert diese über den Webservice. Das <asp:ObjectDataSource>-Steuerelement vor dem DetailsView-Steuerelement in NeuerPassagier.aspx (siehe Listing 5) sorgt dafür, dass das DetailsView-Steuerelement diese Methoden aufruft. Letzteres ist an ObjectDataSource gebunden, und diese verweist auf die Klasse NeuerPassagierManager mit den Methoden Laden() und Einfuegen().

using System;
using System.Collections.ObjectModel;
using System.Web;
using WWWings_Dienstproxies.WWWingsServer;
using WWWings_GO;

public class NeuerPassagierManager
{
public static Passagier Laden()
{
return new Passagier();
}

public void Einfuegen(Passagier pneu)
{
// Neuen Passagier speichern
ObservableCollection<Passagier> GeändertePassagiere
= new ObservableCollection<Passagier>() { pneu };
string Statistik;

BuchungsServiceClient client = new BuchungsServiceClient();
var antwort = client.SavePassagierSet(GeändertePassagiere, out Statistik);
client.Close();

Console.WriteLine("Statistik von SavePassagierSet: " + Statistik);

if (antwort.Count == 1)
{
// Der erste neue Passagier muss der angelegte sein,
// der nun auch die ID enthält!
pneu = antwort[0];
// Den Passagier merken zur Übergabe an Buchung.aspx
HttpContext.Current.Session["Passagier"] = pneu;
}
}
}

Was nun noch fehlt, ist die Navigation zwischen Buchung.aspx und NeuerPassagier.aspx. Dabei gibt es die Anforderung, dass ein beim Verlassen der Buchung.aspx gewählter Flug bei der Rückkehr weiterhin ausgewählt ist und ein in NeuerPassagier.aspx erfasster Flug dann ebenfalls. Für die Kommunikation zwischen zwei Seiten lässt sich der Viewstate nicht verwenden, da er immer seitenbezogen ist. Hier benötigt man serverseitig gespeicherte Sitzungsvariablen. Der Browser erhält zur Wiederkennung des Nutzers einen Cookie oder eine lange ID in der URL. Um beides muss sich ein ASP.NET-Entwickler nicht kümmern.

Der Entwickler muss sich nur die beim Klick auf "Neuer Passagier" in Buchung.aspx die aktuelle Flugauswahl merken und beim Page_Load() der Buchung.aspx.cs prüfen, ob ein gemerkter Flug und/oder Passagier vorhanden ist (beides siehe Listing 6). Dabei sieht man eine kleine, leider nicht umgehbare Inkonsistenz: Beim "Passagier" kann man sich in der Sitzungsvariablen das ganze Passagierobjekt merken. Bei "Flug" kann man sich leider nur die ID des Flugs merken, da das GridView-Steuerelement nur die ID des gewählten Flugs hergibt, nicht aber das ganze Objekt. Zur Vervollständigung fehlt dann nur noch eine Zeile in der Hintergrundcode-Datei von NeuerPassagier.aspx (siehe folgenden Code): Egal, ob der Benutzer "Speichern" oder "Abbrechen" klickt, es geht zurück zu Buchung.aspx.

using System.Web.UI.WebControls;

public partial class NeuerPassagier : System.Web.UI.Page
{
protected void C_Passagier_ModeChanging(object sender,
DetailsViewModeEventArgs e)
{
if (e.CancelingEdit || e.NewMode == DetailsViewMode.Insert)
Response.Redirect("Buchung.aspx");
}

}

Fazit

Mit wenig Aufwand ist eine überzeugende Webanwendung zur Flugbuchung auf Basis der bestehenden Webservices entstanden. ASP.NET kann einige Stärken hinsichtlich der Abstraktion von HTTP, HTML und JavaScript in diesem Beispiel ausspielen, sodass der Webentwickler stark von Infrastrukturcode entlastet wird. Nur ansatzweise erwähnt wurde, welche Möglichkeiten der Webdesigner bietet, um sich die ASPX-Tags zusammenzuklicken.

Im nächsten Teil soll eine XAML-Oberfläche für die Windows Presentation Foundation (WPF) entstehen. Einige Male wird der Entwickler sich dann via Copy & Paste beim Webprojekt bedienen können, aber vieles ist auch wieder ganz anders. (ane)

Dr. Holger Schwichtenberg
leitet das Expertenteam von www.IT-Visions.de, das Beratung und Schulungen im .NET-Umfeld anbietet. Er hält Vorträge auf Fachkonferenzen und ist Autor zahlreicher Fachbücher.

Literatur

Holger Schwichtenberg; ASP.NET 4.0 Entwicklerhandbuch; Microsoft Press 2011