ASP.NET 2.0 - Mitglieder- und Rollenverwaltung mit IIS, Teil 2: Implementierung

Veröffentlicht: 21. Feb 2006

Von Peter Kellner

In diesem Artikel wird die Verwaltung von Mitgliedschafts- und Rollendatenbanken auf einem IIS-Produktionsserver anhand einer ASP.NET 2.0-Anwendung mit drei Ebenen beschrieben (17 gedruckte Seiten).

Klicken Sie hier, um das Codebeispiel zu diesem Artikel herunterzuladen.

Auf dieser Seite

 Einführung
 Verwendete Technologien
 Anwendung und Projekt
 Details zu "ObjectDataSource"
 Der Rückgabewert der "Select"-Methode (Auflistung)
 Die "Select"-Methode
 Benutzerdefinierte Sortierkriterien
 "ObjectDataSource" in einem "GridView" (Datensteuerelement)
 Schlussbemerkung
 Der Autor

Einführung

Membership Editor
Abbildung 1: Membership Editor

Microsoft Visual Studio 2005 enthält keine schlüsselfertige Lösung zum Verwalten von Mitgliedschafts- und Rollendatenbanken von Microsoft IIS. Dies stellt ein Problem dar, wenn Sie eine Anwendung aus der Entwicklungsumgebung in der Produktionsumgebung eines IIS-Servers zur Verfügung stellen. Das von Microsoft bereitgestellte Dienstprogramm, ASP.NET Web Configuration, kann lediglich in einer Entwicklungsumgebung ausgeführt werden, nicht jedoch in der Produktionsumgebung. Dieser Artikel und der zugehörige Code lösen dieses Problem durch Implementieren einer Anwendung mit drei Ebenen zum Verwalten von Mitgliedern und Rollen. Dazu werden Microsoft ASP.NET-Standardtools eingesetzt. Die Lösung kann daher in jeder ASP.NET 2.0-Umgebung ausgeführt werden, einschließlich IIS. Die Lösung ist flexibel und kann vorhandenen ASP.NET 2.0-Websiteprojekten sehr einfach hinzugefügt werden.

Die Ebenen dieser Lösung werden folgendermaßen definiert. Die erste Ebene, die ASP.NET-Seite (bekannt als Darstellungsschicht), arbeitet über ein Datenquellen-Objekt mit zwei Geschäftsobjekten zusammen. Diese Geschäftsobjekte dienen als mittlere Ebene. Sie sind Wrapper für Mitglieder und Rollen. Die dritte Ebene (Back-End) besteht aus den von ASP.NET bereitgestellten APIs zur Mitgliedschafts- und Rollenverwaltung. Die Objekte der mittleren Ebene können einem ASP.NET 2.0-Projekt einfach per Drag & Drop hinzugefügt und ohne Änderungen direkt verwendet werden.

Dieser Artikel erläutert detailliert die Implementierung der mittleren Ebene, d. h. der Datenobjekte und des mit ihnen verknüpften ObjectDataSource-Objekts. Anschließend wird die Verwendung dieser Objekte in einem ASP.NET-Webprojekt erläutert, das Microsoft SQL Server Express 2005 verwendet (wird mit Visual Studio 2005 ausgeliefert). Die von Microsoft bereitgestellte Membership-API verwendet eigene Providertechnologie, daher ist die hier vorgestellte Lösung datenbankunabhängig. Die Informationen über Mitgliedschaften und Rollen können ebenso über LDAP, SQL Server oder Oracle bezogen werden.

 

Verwendete Technologien

Das "ObjectDataSource"-Objekt

Es werden zwei Instanzen von ObjectDataSource definiert. Eine ist für Mitgliedschaftsdaten (Benutzername, Erstellungsdatum, Genehmigung usw.), die andere für Rollen (Administrator, Freunde usw.) vorgesehen. Beide Datenquellen bieten einen vollständigen Satz an Datenzugriffsmethoden, d. h. beide verfügen über Memberfunktionen, die Einfügevorgänge, Updates, Löschvorgänge und Abfragen ausführen. Beide ObjectDataSource-Instanzen geben eine generische Liste zurück. Daher werden in einem GridView automatisch die Namen der Eigenschaftenwerte des ObjectDataSource-Objekts als Spaltennamen verwendet. Darüber hinaus ist eine benutzerdefinierte Sortierung implementiert, so dass die Benutzer auf eine Spaltenüberschrift im GridView klicken können, um die Daten wie gewünscht auf- oder absteigend zu sortieren.

SQL Server Express 2005 und "Web.Config"

Die Datenanbieterquelle für Mitgliedschafts- und Rollendatenbanken ist SQL Server Express 2005. Die dafür notwendigen Einträge befinden sich in der Datei web.config. Weiter unten in diesem Artikel wird das Einrichten eines vollständig neuen Projekts kurz erörtert. Die Verbindungszeichenfolge für SQL Server Express 2005 wird nicht in die Datei web.config eingetragen, da sie bereits in der Datei Machine.Config definiert ist, die als Standardbestandteil des Microsoft .NET 2.0 Framework enthalten ist.

Kompatibel mit IIS (5.1 und 6.0)

Als Webserver kann sowohl die Version 5.1 als auch die Version 6.0 von IIS verwendet werden. Sie müssen IIS verwenden, um Tests mit mehreren an der Webanwendung angemeldeten Benutzern durchführen zu können. Der integrierte Entwicklungswebserver kann den Status verschiedener gleichzeitig angemeldeter Benutzer nicht korrekt überwachen. Obwohl das Webkonfigurationstool von ASP.NET zur Zusammenarbeit mit IIS konfiguriert werden kann, wurden die zusätzlich notwendigen Sicherheitsmaßnahmen dafür nicht durchgeführt.

Das Steuerelement "GridView"

Das Steuerelement GridView wird zur Anzeige der Daten sowohl von Mitgliedschaften als auch von Rollen verwendet. Wie bereits erwähnt, werden aufgrund der Verwendung eines generischen Typs für ObjectDataSource die Spaltennamen des GridView automatisch nach den Eigenschaftenwerten von ObjectDataSource benannt. Ohne den generischen Typ würden die Spaltennamen auf wenig aussagekräftige Standardwerte gesetzt, jeder Name müsste manuell angepasst werden.

 

Anwendung und Projekt

Das zur Ausführung dieses Dienstprogramms notwendige Projekt ist sehr einfach und eigenständig. Die Projektdateien, die zum Herunterladen zur Verfügung stehen, enthalten ein vollständig funktionierendes Beispiel. Da kein direkter Datenbankzugriff auf Benutzer und Rollen verfügbar ist, müssen Sie auf die drei Datenobjekte zugreifen (MembershipDataObject.cs, MembershipUserSortable.cs und RoleDataObject.cs, siehe Abbildung 2).

Projekt "Membership Editor"
Abbildung 2: Projekt "Membership Editor"

Im Ordner SamplePages befinden sich weitere Beispiele, die den Einsatz der zuvor erwähnten Module zeigen. Ein Beispiel, Membership.aspx wird in der Abbildung 1 dargestellt. Es kann zum Auswählen, Aktualisieren, Einfügen und Löschen von Mitgliedern und Rollen verwendet werden, ebenso zum Zuweisen von Rollen zu Mitgliedern.

Bei einer funktionierenden ASP.NET 2.0-Anwendung mit eigenem Mitgliedschaftsmodul benötigen diese Seiten keine, über die bereits vorhandene hinausgehende, externe Konfiguration. Diese Dateien können direkt in ein Projekt kopiert werden, um sofort einsatzfähig zu sein.

Wenn es sich um die erste Implementierung einer Mitgliedschafts- und Rollenverwaltung in einer Anwendung handelt, sieht der Vorgang zum Erstellen einer Anwendung mit diesen Objekten folgendermaßen aus:

  1. Erstellen Sie in Visual Studio 2005 ein neues Webprojekt vom Typ ASP.NET-Website.

  2. Klicken Sie im Menü auf Website / ASP.NET-Konfiguration.

  3. Folgen Sie den Schritten im Assistenten (1 bis 7), um einige Beispielbenutzer und -rollen zu erstellen. Dadurch wird eine gültige Datei web.config im aktuellen Projekt erstellt, die ausreichende Informationen enthält, um eine Mitgliederverwaltung durchführen zu können. In der Standardeinstellung der Konfiguration wird SQL Server Express 2005 verwendet.

  4. Schließen Sie die drei CS-Dateien in das Projekt ein und fügen Sie anschließend die ASPX-Beispielseiten hinzu.

 

Details zu "ObjectDataSource"

Die ObjectDataSource-Technologie ermöglicht das Erstellen einer Datenquelle, die sich ähnlich wie eine SqlDataSource verhält: Sie legt ebenfalls Schnittstellen zum Auswählen, Aktualisieren, Einfügen und Löschen von Datensätzen (oder ähnlichen Objekten) in einem persistenten Datenspeicher (bspw. einer Datenbank) offen. In den nächsten Abschnitten dieses Artikels wird das Objekt (bzw. die Klassendatei) näher erläutert, das ObjectDataSource zum Bearbeiten von Mitgliedschaften verwendet. Der entsprechende Dateiname im Projekt lautet MembershipUserODS.cs.

Die Klasse (MembershipUserODS)

Da die Daten über die Microsoft Membership-API abgerufen werden, wird ein ObjectDataSource-Objekt zur Lösung des Problems verwendet. Der erste Schritt besteht aus dem Erstellen einer eigenständigen Klasse, die als Wrapper für MembershipUser dient und auf diese Weise mit dem ObjectDataSource-Objekt verknüpft werden kann. Das folgende Beispiel zeigt eine Reihe üblicher Methoden, die implementiert werden müssen. In den folgenden Abschnitten des Artikels wird die Implementierung jeder Memberfunktion erläutert. Viele Einzelheiten werden in diesem Artikel nicht besprochen, sie sind jedoch in dem bereitgestellten Quellcode enthalten.

[DataObject(true)
public class MembershipUserWrapper {

  [DataObjectMethod(DataObjectMethodType.Select, true)]
  static public Collection<MembershipUserWrapper> GetMembers(string
       sortData) {
    return GetMembers(true, true, null, sortData); 
  }

  [DataObjectMethod(DataObjectMethodType.Insert, true)]
  static public void Insert(string UserName, bool isApproved,
string comment, DateTime lastLockoutDate, ...) {
  }
        
  [DataObjectMethod(DataObjectMethodType.Delete, true)]
  static public void Delete(object UserName, string Original_UserName){
    Membership.DeleteUser(Original_UserName, true);
  }
  
  [DataObjectMethod(DataObjectMethodType.Update, true)]
  static public void Update(string original_UserName,string email,...){ 
  }
}

Die Klassendeklaration

Aufgrund des Attributs [(DataObject(true)] ist die oben dargestellte Klassendeklaration etwas Besonderes. Dieses Attribut legt für den Assistenten zum Erstellen einer ObjectDataSource-Klasse in Visual Studio 2005 fest, ausschließlich Member mit diesem speziellen Attribut zu berücksichtigen, wenn in einer Datenklasse nach DataObject-Objekten gesucht wird. Betrachten Sie das Beispiel in dem Abschnitt, in dem diese Klasse einer GridView-Komponente zugewiesen wird.

Die "Insert"-Methode

Die Details jedes Abschnitts beinhalten eine sehr einfache Verwendung der von Microsoft bereitgestellten Membership-API. Im Folgenden wird beispielhaft eine typische Insert-Methode näher erläutert.

[DataObjectMethod(DataObjectMethodType.Insert,true)]
static public void Insert(string userName, string password,)
{
   MembershipCreateStatus status;
      Membership.CreateUser(userName, password,);
}

Die Klasse Insert ist polymorph, es können also verschiedene Insert-Methoden für unterschiedliche Zwecke vorhanden sein. Es kann beispielsweise notwendig sein, dynamisch zu entscheiden, ob ein erstellter Benutzer unter bestimmten Umständen zugelassen wird. Ein Beispiel: Ein auf der Administratorseite neuer Benutzer möchte weitere Benutzer erstellen, die als Standardeinstellung "zugelassen" erhalten sollen, während die Benutzerregistrierungsseite in der Standardeinstellung "nicht zugelassen" vorsieht. Um dies zu erreichen, ist eine weitere Insert-Methode mit einem zusätzlichen Parameter notwendig. Im Folgenden wird eine Insert-Methode dargestellt, die diesen Zweck erfüllt.

[DataObjectMethod(DataObjectMethodType.Insert,false)]
static public void Insert(string userName, string password, bool isApproved)
{
MembershipCreateStatus status;
   Membership.CreateUser(UserName, password,,
      isApproved, out status);
}

Wie bei den anderen hier dargestellten Methoden entsprechen die Beispiele nicht tatsächlich dem zum Artikel gehörenden Quellcode. Die hier dargestellten Beispiele sollen die übliche Verwendung verdeutlichen. Vollständigere und kommentierte Verwendungsmöglichkeiten finden Sie im Quellcode.

Die "Update"-Methode

Die Update-Methode stellt eine einfache Implementierung der Membership-API dar. Ähnlich der Insert-Methode können zahlreiche Implementierungen der Update-Methode vorliegen. An dieser Stelle wird lediglich eine Implementierung dargestellt. In dem zum Herunterladen verfügbaren Code gibt es weitere polymorphe Implementierungen der Update-Methode, einschließlich einer Implementierung, in der die IsApproved-Eigenschaft festgelegt wird (siehe folgendes Beispiel).

[DataObjectMethod(DataObjectMethodType.Update,false)]
static public void Update(string UserName,bool isApproved)
{
   bool dirtyFlag = false;
   MembershipUser mu = Membership.GetUser(UserName);
   if (mu.isApproved != isApproved)
   {
      dirtyFlag = true;
      mu.IsApproved = isApproved;
   }
   if (dirtyFlag == true)
   {
      Membership.UpdateUser(mu);
   }
}

Die "Delete"-Methode

Die Delete-Methode ist die einfachste und verwendet nur einen Parameter: UserName.

static public void Delete(string UserName)
{
   Membership.DeleteUser(UserName,true);
}

Die "Select"-Methode mit einem Sortierungsattribut

Die Select-Methode (in diesem Fall GetMembers) besteht aus mehreren Komponenten, von denen jede eine Diskussion wert ist. Zunächst werden die Rückgabewerte erörtert, dann die Methode selbst und schließlich die Art der Sortierung der Rückgabewerte.

 

Der Rückgabewert der "Select"-Methode (Auflistung)

Der Rückgabewert der Select-Methode (ebenfalls als Get bezeichnet) besteht aus einer generischen Auflistungsklasse. Generische Typen werden verwendet, da das letztendlich mit der Klasse verknüpfte ObjectDataSource-Objekt Reflektion einsetzt, um die Spaltennamen und -typen zu ermitteln. Diese Namen und Typen werden mit jeder zurückgegebenen Datenzeile verknüpft. Auf dieselbe Weise verwendet ein SqlDataSource-Objekt die Datenbank-Metadaten einer Tabelle oder gespeicherten Prozedur, um die Spaltennamen jeder Zeile zu ermitteln. Da es sich beim Rückgabetyp der Select-Methode um eine MembershipUserWrapper-Klasse handelt, die von MembershipUser erbt, entsprechen die meisten Eigenschaften dieser Klasse denen von MembershipUser. Zu diesen Eigenschaften gehören:

  • ProviderUserKey

  • UserName

  • LastLockoutDate

  • CreationDate

  • PasswordQuestion

  • LastActivityDate

  • ProviderName

  • IsLockedOut

  • Email

  • LastLoginDate

  • IsOnline

  • LastPasswordChangedDate

  • Comment

Ein sehr nützliches Feature von Eigenschaftswerten besteht darin, dass sie schreibgeschützt (keine Set-Methode) sein können oder dass nur Schreibzugriff (keine Read-Methode) und natürlich Lese- und Schreibzugriff darauf möglich sein können. Der Assistent zum Erstellen der ObjectDataSource-Klasse erkennt dies und erstellt die geeigneten Parameter, so dass bei der Darstellung des Datensteuerelements (unter Verwendung von ObjectDataSource) lediglich die aktualisierbaren Felder (Lese- und Schreibzugriff) zum Bearbeiten freigegeben sind. Das bedeutet, dass Sie bspw. die UserName-Eigenschaft nicht ändern können. Im Moment mag dies keinen Sinn ergeben, nach einer ausführlicheren Erörterung von ObjectDataSource und den Datenkomponenten wird dies jedoch klar werden.

 

Die "Select"-Methode

Auch die Select-Methode ist, wie auch Insert und Update, polymorph. Es kann so viele verschiedene Select-Methoden geben, wie es unterschiedliche Szenarios gibt. So kann es beispielsweise wünschenswert sein, die Select-Methode zu verwenden, um Benutzer auf Basis der Eigenschaften "zugelassen", "nicht zugelassen" oder beider Eigenschaften auszuwählen. Üblicherweise gibt es eine Get-Methode, die die maximale Anzahl von Parametern verwendet, während die anderen Get-Methoden diese aufrufen. In unserem Fall gibt es drei Get-Methoden: eine zum Abrufen aller Datensätze, eine zum Abrufen auf Basis des Zulassungsstatus, und eine zum Abrufen eines einzelnen Datensatzes auf Basis einer Auswahlzeichenfolge. Im folgenden Beispiel wird die Methode aufgerufen, die alle Benutzer zurückgibt. Durch Festlegen beider Booleschen Werte auf TRUE werden alle Benutzer zurückgegeben.

[DataObjectMethod(DataObjectMethodType.Select, true)]
static public List<MembershipData> GetMembers(string sortData)
{
   return GetMembers(true,true,null,null);
}

Im nächsten Beispiel wird eine ausführlichere Get-Methode dargestellt. Dieses Beispiel stellt nur den Anfang der Methode dar. Zu den nicht dargestellten Details der Methode gehören das Abschließen der Eigenschaften-Zuweisungen, das Filtern des Genehmigungsstatus und das Zurückweisen der Datensätze, die den Kriterien nicht entsprechen, sowie das Anwenden der Sortierkriterien. Diesem Beispiel folgt eine Erörterung der Sortierkriterien. (Beachten Sie, dass der Aufruf von GetAllUsers für eine Datenbank mit mehr als lediglich ein paar Hundert Benutzern rasch zu einem sehr aufwändigen Vorgang werden kann.)

[DataObjectMethod(DataObjectMethodType.Select, true)]
static public List<MembershipData> GetMembers(bool AllApprUsers, 
    bool AllNotApprUsers, string UserToFind, string sortData)
{
   List<MembershipData> memberList = new List<MembershipData>();
   MembershipUserCollection muc = Membership.GetAllUsers();
   foreach (MembershipUser mu in muc)
   {
      MembershipData md = new MembershipData();
      md.Comment = mu.Comment;
      md.CreationDate = mu.CreationDate;
            ...

 

Benutzerdefinierte Sortierkriterien

Beachten Sie im vorhergehenden Code, dass ein Zeichenfolgenparameter mit der Bezeichnung sortData an GetMembers übergeben wird. Wird SortParameterName als eines der Attribute in der Deklaration von ObjectDataSource angegeben, wird dieser Parameter automatisch an alle Select-Methoden übergeben. Der Wert entspricht dem im Attribut SortExpression in der Spalte des Datensteuerelements angegebenen Namen. In unserem Fall handelt es sich bei dem Datensteuerelement um GridView.

Die Comparer-Methode wird auf Basis des Parameters sortName für die Methode GetMembers aufgerufen. Da diese ASP.NET-Webseiten statusfrei sind, müssen wir davon ausgehen, dass die Art der aktuellen Sortierung (auf- oder absteigend) im Ansichtszustand gespeichert wird. Jeder Aufruf kehrt die Richtung des vorherigen Aufrufs um. Praktisch wechselt die Sortierung zwischen auf- und absteigend, wenn der Benutzer auf den Spaltenheader klickt.

Beim Verwenden eines GridView enthält der an GetMembers(sortData) übergebene Parameter die Daten des SortExpression-Attributs der jeweiligen GridView-Spalte. Wenn eine Anforderung zum absteigenden Sortieren erfolgt, wird das Wort "DESC" an das Ende der Sortierzeichenfolge angehängt. Wenn der Benutzer bspw. das erste Mal auf die Spalte Email klickt, wird der sortData-Wert "Email" an GetMembers übergeben. Beim erneuten Klicken des Benutzers auf diese Spalte erhält der Parameter sortData den Wert "Email DESC", anschließend "Email", dann wieder "Email DESC" usw. Insbesondere sei darauf hingewiesen, dass beim ersten Laden der Seite der Parameter sortData als Zeichenfolge der Länge Null (nicht NULL) übergeben wird. Im Folgenden wird das Wesentliche der GetMembers-Methode dargestellt, die Daten abruft und so sortiert, dass sie in der korrekten Reihenfolge zurückgegeben werden.

[DataObjectMethod(DataObjectMethodType.Select, true)]
static public List<MembershipData> GetMembers(string sortData)
{
  List<MembershipData> memberList = new List<MembershipData>();
  MembershipUserCollection muc = Membership.GetAllUsers();
  List<MembershipUser> memberList = new List<MembershipUser>(muc);

  foreach (MembershipUser mu in muc)
  {
    MembershipData md = new MembershipData(mu);
    memberList.Add(md);
  }

  ... Code that implements Comparison

   memberList.Sort(comparison);
  
  return memberList;
}

Im nächsten Abschnitt wird dies deutlicher, wenn diese Methode in ein GridView aufgenommen wird.

Deklaration von "ObjectDataSource"

Der einfachste Weg zum Deklarieren einer ObjectDataSource-Klasse besteht im Einfügen eines auf der Symbolleiste angezeigten Datensteuerelements per Drag & Drop, nachdem zuvor eine leere ASP.NET-Seite mit dem Visual Studio 2005-Assistenten erstellt wurde. Nach dem Erstellen der ObjectDataSource-Klasse kann in der oberen rechten Ecke dieser neu erstellten Klasse eine kleine Markierung verwendet werden; anschließend wird nach dem Klicken auf Datenquelle konfigurieren ein Assistent mit dem Titel "Datenquelle konfigurieren ? ObjectDataSource1" geöffnet (siehe Abbildung 3).

Konfigurieren von "ObjectDataSource"
Abbildung 3: Konfigurieren von "ObjectDataSource"

An dieser Stelle werden zwei Klassen angezeigt, die für das Verknüpfen mit einer ObjectDataSource-Klasse verfügbar sind. Bei MembershipUserODS handelt es sich um den primären Gegenstand dieses Artikels. RoleDataObject ist grundsätzlich dasselbe, kapselt jedoch Mitgliedschaftsrollen. Bedenken Sie, dass es sich bei dieser Darstellung nur um die Objekte handelt, die mit dem speziellen Klassenattribut [DataObject(true)] deklariert wurden, wie im Abschnitt "Die Klassendeklaration" beschrieben.

Nach dem Auswählen von MembershipUserODS wird ein Dialogfeld mit vier Registerkarten angezeigt. Die in der Klasse MembershipUserODS aufrufbaren Methoden werden auf diesen Registerkarten definiert. Die Methoden für Select, Update, Insert und Delete lassen sich in MembershipUserODS mit Memberfunktionen verknüpfen. In vielen Fällen werden in der Klasse mehrere Methoden für jeden Vorgang verfügbar sein. Je nach gewünschtem Szenario müssen Sie die geeignete Methode auswählen. Alle vier Registerkarten zeigt Abbildung 4. In der Standardeinstellung werden die mit dem speziellen Attribut [DataObjectMethod(DataObjectMethodType.Select, false)] gekennzeichneten Member auf den Registerkarten gefüllt. Dieses spezielle Attribut ist natürlich die Standardeinstellung für Select. Das Ändern des Ausdrucks DataObjectMethodType.Select in DataObjectMethodType.Insert, DataObjectMethodType.Update und DataObjectMethodType.Delete passt die Standardeinstellungen für die Registerkarten entsprechend an. Der zweite Parameter, ein Boolescher Wert, kennzeichnet diese Methode (Methoden können polymorph definiert werden) als Standardmethode und als im Registerkarten-Steuerelement zu verwendende Methode.

Die "Select"-Methode

Wie bereits im Abschnitt über die MembershipUserODS-Klasse erwähnt, gibt die GetMembers-Funktion eine generische Auflistungsklasse zurück. Dadurch wird das ObjectDataSourceMembershipUser-Steuerelement in die Lage versetzt, Reflektion zu verwenden und die mit diesem GetMembers-Aufruf verknüpften Parameter zu ermitteln. In diesem Fall sind die zum Aufruf von GetMembers verwendeten Parameter returnAllApprovedUsers, returnAllNotApprovedUsers, userNameToFind und sortData. Auf dieser Grundlage stellt sich die aktuelle Definition der neuen ObjectDataSource-Klasse wie folgt dar.

Zuweisen der "Select"-Methode
Abbildung 4: Zuweisen der "Select"-Methode

<asp:ObjectDataSource ID="ObjectDataSourceMembershipUser"runat="server" 
    SelectMethod="GetMembers" UpdateMethod="Update" 
    SortParameterName="SortData"
    TypeName="MembershipUtilities.MembershipDataODS" 
    DeleteMethod="Delete" InsertMethod="Insert" >
    <SelectParameters>
      <asp:Parameter Name="returnAllApprovedUsers" Type="Boolean" />
      <asp:Parameter Name="returnAllApprovedUsers" Type="Boolean"/>
      <asp:Parameter Name="usernameToFind"         Type=" String" />
      <asp:Parameter Name="sortData"               Type=" String" />
    </SelectParameters>
    ...
    ...
</asp:ObjectDataSource>

Die "Insert"-Methode

Die Insert-Methode ist in diesem Fall mit der Memberfunktion Insert() verknüpft. Beachten Sie den Aufruf dieser Methode mit lediglich zwei Parametern: UserName und Password (siehe Abbildung 5). Die Anzahl der Parameter muss der Anzahl der Parameter in der Deklaration von ObjectDataSource entsprechen. Die Parameterdeklaration von ObjectDataSource wird im Folgenden dargestellt. Es gibt eine zweite definierte Insert Member-Funktion, die einen dritten Parameter hinzufügt: approvalStatus. Wenn die Funktionalität dieser ObjectDataSource-Klasse beim Festlegen des approvalStatus das Einfügen beinhalten soll, sollten Sie die andere Methode aus der Dropdown-Liste auswählen. Dies fügt die folgenden InsertParameters in die ASPX-Seite. Wenn die Methode mit zwei Parametern ausgewählt wird, enthält der Block nicht den Eintrag asp:Parameter mit dem Namen isApproved. Auch hier gilt, dass dieses Beispiel nicht vollständig mit dem zur Verfügung gestellten Quellcode übereinstimmt und nur als Beispiel dient. Der dem Artikel beigefügte Quellcode ist wesentlich umfassender.

Zuweisen der "Insert"-Methode
Abbildung 5: Zuweisen der "Insert"-Methode

<asp:ObjectDataSource ID="ObjectDataSourceMembershipUser"runat="server" 
    SelectMethod="GetMembers"UpdateMethod="GetMembers" 
    SortParameterName="SortData"
    TypeName="MembershipUtilities.MembershipDataObject" 
    DeleteMethod="Delete" InsertMethod="Insert">
    <InsertParameters>
        <asp:Parameter Name="userName" Type="String" />
        <asp:Parameter Name="password" Type="String" />
        <asp:Parameter Name="isApproved" Type="Boolean" />
    </InsertParameters>
    ...
</asp:ObjectDataSource>

Bedenken Sie auch, dass die Verwendung einer Insert-Methode mit minimaler Anzahl von Parametern das Festlegen eines Standardkennworts innerhalb der Methode erfordert. Dies ist für ein Produktionssystem ungeeignet. Der beigefügte Quellcode enthält ein besseres Beispiel zur Handhabung von Insert-Methoden. Betrachten Sie insbesondere die Seite Membership.aspx hinsichtlich dieser Funktionalität.

Die "Update"-Methode

Die Update-Methode ist in diesem Fall mit der Memberfunktion Update() verknüpft. Beachten Sie, dass diese Methode mit mehreren Parametern aufgerufen wird: UserName, Email, isApproved und Comment (siehe Abbildung 6). Darüber hinaus gibt es eine weitere Update-Methode, die sämtliche aktualisierbaren Parameter enthält. Dies ist hilfreich beim Erstellen eines Steuerelements, das die meisten Möglichkeiten zum Aktualisieren bietet. Wie bei Insert wird für diese ObjectDataSource-Klasse die geeignete Update-Methode ausgewählt. Nach dem Fertigstellen des Assistenten werden automatisch UpdateParameters-Einträge erstellt, wie im Folgenden dargestellt.

Zuweisen der "Update"-Methode
Abbildung 6: Zuweisen der "Update"-Methode

<asp:ObjectDataSource ID="ObjectDataSourceMembershipUser"runat="server" 
    SelectMethod="GetMembers" InsertMethod="Insert"
    SortParameterName="SortData"
    TypeName="MembershipUtilities.MembershipUserODS" 
    UpdateMethod="Update" DeleteMethod="Delete">
    <UpdateParameters>
        <asp:Parameter Name="Original_UserName" />
        <asp:Parameter Name="email" Type="String" />
        <asp:Parameter Name="isApproved" Type="Boolean" />
        <asp:Parameter Name="comment" Type="String" />
    </UpdateParameters>
    ...
    ...
</asp:ObjectDataSource>

Die "Delete"-Methode

Die Delete-Methode ist in diesem Fall mit der Memberfunktion Delete() verknüpft. Es ist natürlich lediglich eine Delete-Methode notwendig (siehe Abbildung 7). Im Folgenden finden Sie die Deklaration der ObjectDataSource-Klasse, die diese Delete-Methode unterstützt.

Zuweisen der "Delete"-Methode
Abbildung 7: Zuweisen der "Delete"-Methode

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
    SelectMethod="GetMembers" InsertMethod="Insert"
    SortParameterName="SortData"
    TypeName="MembershipUtilities.MembershipUserODS" 
    UpdateMethod="Update" DeleteMethod="Delete">
    <DeleteParameters>
        <asp:Parameter Name="UserName" />
        <asp:Parameter Name="Original_UserName" />
    </DeleteParameters>
    ...
</asp:ObjectDataSource>

Die Klasse (RoleDataObject)

Ähnlich wie Mitgliedschaften werden Rollen in einem eigenen DataObject eingerichtet. Da es keine Besonderheiten bei Rollen gibt, führt dieser Artikel keine weiteren Einzelheiten dazu aus. Die Kenntnisse über das Einrichten von DataObjects für Mitgliedschaften können auf das Einrichten von Rollen übertragen werden. Bei Mitgliedschaften ist das für die Kapselung der Membership-API zuständige Microsoft C#-Objekt MembershipDataObject.cs. Die entsprechende Klasse zur Kapselung der Role-API ist RoleDataObject.cs.

 

"ObjectDataSource" in einem "GridView" (Datensteuerelement)

Die Klassendeklarationen für Mitgliedschaftsbenutzer und Rollen wurden in den vorhergehenden Abschnitten dieses Artikels erstellt. Ein vollständiges ObjectDataSource-Objekt wurde ebenfalls in eine ASP.NET-Seite integriert. Der letzte Schritt besteht aus dem Erstellen der Benutzeroberfläche bzw. der Benutzerebene oder Darstellungsschicht. Da bereits ein Großteil der Arbeit durch die erstellten Objekte durchgeführt wird, reicht die Erstellung eines einfachen GridView und dessen Verknüpfung mit der ObjectDataSource-Klasse. Folgende Schritte sind auszuführen:

  1. Platzieren Sie im ASP.NET-Seitendesigner eine GridView-Datenkomponente per Drag & Drop auf die Seite, die mit der zuvor erstellten ObjectDataSource-Klasse verknüpft ist.

  2. Aktivieren Sie das Auswählen, Löschen, Aktualisieren, Einfügen und Sortieren.

In Abbildung 8 wird das Dialogfeld zum Konfigurieren des GridView-Steuerelements dargestellt.

Konfigurieren des "GridView"
Abbildung 8: Konfigurieren des "GridView"

An dieser Stelle sei angemerkt, dass DataKeyNames im unten dargestellten GridView-Steuerelement automatisch festgelegt wird. Ursache ist das Markieren des primären Schlüssels in der MembershipUserSortable-Klasse mit dem Attribut [DataObjectField(true)], wie im Folgenden dargestellt. Beachten Sie weiterhin die Notwendigkeit zum Einrichten einer Standardeigenschaft in der Klasse, die MembershipUser erweitert, da UserName eine Eigenschaft der MembershipUser-Klasse ist. Da es sich um eine schreibgeschützte Eigenschaft handelt, wird lediglich eine Get-Methode deklariert. (UserName ist öffentlich virtuell für MembershipUser.)

[DataObjectField(true)]
public override string UserName {
  get { return base.UserName;
}

Ein Attribut muss für das GridView manuell eingetragen werden: der primäre Schlüssel muss im Steuerelement festgelegt werden. Zu diesem Zweck verknüpfen Sie das Attribut DataKeyName mit UserName. Die Deklaration des GridView wird im Folgenden dargestellt.

<asp:GridView ID="GridView1" DataKeyNames="UserName" runat="server" 
        AllowPaging="True" AutoGenerateColumns="False"
        DataSourceID="ObjectDataSourceMembershipUser"
        AllowSorting="True">
    <Columns>
    ...
    ...

 

Schlussbemerkung

Als Ergebnis sollten Sie an dieser Stelle mit dem Erstellen einer ASP.NET-Anwendung mit drei Ebenen vertraut sein. Gleichzeitig verfügen Sie jetzt über zwei Objekte, die Sie zukünftig zum Kapseln von Mitgliedern und Rollen verwenden können. Sie könnten das DetailView-Steuerelement verwenden und in wenigen Minuten eine vollständige DetailView-Oberfläche erstellen, die Funktionalitäten zur Navigation, zum Einfügen, Aktualisieren und Löschen von Mitgliedern bereitstellt. Versuchen Sie es!

Auf die Implementierungen der Funktionen zum Hinzufügen, Aktualisieren und Löschen von Mitgliedern und Rollen bin ich nicht weiter eingegangen. Wenn Sie den Quellcode betrachten, werden Sie feststellen, dass ich die APIs auf sehr einfache Weise verwendet habe. In diesem Artikel ist eine Beschreibung dieser Aufrufe in aller Ausführlichkeit nicht sinnvoll, beim Arbeiten mit diesem Thema werden Sie diese kennen lernen.

Glücklicherweise war ich in diesem Jahr auf der MS TechEd in Orlando und der PDC in Los Angeles, dort konnte ich viele Fragen direkt an das ASP.NET-Team richten. Insbesondere möchte ich Brad Millington und Stefan Schackow für das Beantworten meiner zahlreichen Fragen in diesen Wochen danken, und Jeff King und Brian Goldfarb für ihre Hilfe bei der Verbesserung dieses Artikels. In gewisser Weise ist dieser Artikel eine Gegenleistung, damit sie in Zukunft hoffentlich weniger Fragen beantworten müssen.

 

Der Autor

Peter Kellner gründete 1990 das Unternehmen 73rd Street Associates, in dem er erfolgreich Systeme zur Organisation in Universitätsklinken, Verwaltung von Versicherungsunternehmen und schlüsselfertige Software zur Verwaltung von Arztpraxen an über 500 Kunden auslieferte. Zehn Jahre später, im Jahr 2000, wurde 73rd Street Associates von einem großen Versicherungsunternehmen gekauft. Peter begann eine neue berufliche Laufbahn als unabhängiger Softwareberater. Zu den Technologien, mit denen er sich derzeit beschäftigt, gehören ASP.NET, Oracle, Java, VoIP und in Kürze SQL Server. Seine Freizeit widmet Peter hauptsächlich dem Motorradfahren. Er ist damit bereits rund um den Globus gefahren. Zuletzt fuhr Peter mit seiner Frau Tammy in 27 Tagen durch die USA, von Kalifornien nach Georgia.

Seine Blogsite finden Sie unter http://peterkellner.net/ (in englischer Sprache). Diesen Artikel und den zugehörigen Code finden Sie im Downloadbereich.