ASP NET Tutorial Linq to SQL

Document Sample
ASP NET Tutorial Linq to SQL Powered By Docstoc
					ASP.NET Tutorial (Linq-to-SQL)
Inhaltsverzeichnis
Überblick ......................................................................................................................................................................... 2
   Features der fertigen Anwendung................................................................................................................................ 2
   Voraussetzungen ......................................................................................................................................................... 2
   Struktur der Vorlage .................................................................................................................................................... 2
   BusinessLogic............................................................................................................................................................... 2
   Homepage ................................................................................................................................................................... 2
Erstellen der Webanwendung.......................................................................................................................................... 2
   Anlegen einer Website mit Masterpage ....................................................................................................................... 2
   Anlegen einer Startseite............................................................................................................................................... 3
   Anlegen der weiteren Seiten ........................................................................................................................................ 4
   Passwortschutz einrichten ........................................................................................................................................... 4
   Registrieren von Benutzern.......................................................................................................................................... 6
   Anlegen des Gästebuchs .............................................................................................................................................. 6
   Gästebuch um Ajax Funktionalität erweitern ............................................................................................................... 8
   Lokalisierung der ASP.NET-Anwendung........................................................................................................................ 8
   Testen der Anwendung ................................................................................................................................................ 9
Was muss bei einer „richtigen“ ASP.NET noch beachtet werden? .................................................................................... 9
   Anmerkungen zu diesem Tutorial................................................................................................................................. 9
   Allgemeines ................................................................................................................................................................. 9
Anhang .......................................................................................................................................................................... 10
   Die Datenbank ........................................................................................................................................................... 10
Überblick

Features der fertigen Anwendung
       Ein Gästebuch in dem nur registrierte Benutzer Einträge verfassen dürfen
       Es gibt 2 Rollen (Editor, Admin). Der Admin darf zusätzlich zum Editor auch Einträge löschen
       Es soll möglich sein sich als neuer Benutzer zu registrieren
       Einträge sollen in einer Datenbank gespeichert werden
       Das Gästebuch soll zum Schluss um Ajax-Funktionalität erweitert werden

Voraussetzungen
       Visual Studio 2008 mit SQL Server Express (MSDN-AA oder Visual Studio 2008 Express)

Struktur der Vorlage
Die Vorlage (Vorlage_(Linq-to-SQL).zip) beinhaltet die Datei „Tutorial.sln“, damit kann das gesamte Projekt (Solution) in
Visual Studio geladen werden. Die Solution besteht aus den beiden Teilprojekten, „BusinessLogic“ und „Homepage“.

Im Projekt „Homepage“ soll die Webapplikation entstehen, diese ist noch zu implementieren.

Das Projekt „BusinessLogic“ kapselt den Zugriff auf die Datenbank, die benötigten Methoden sind bereits fertig
implementiert.

BusinessLogic
In der Businesslogik gibt es im wesentlichen folgende Dateien:

       Database.dbml, dies ist das verwendete Datenbankschema als sog. LINQ-TO-SQL-Provider. Das ist unter .NET 3.5
        der (momentan) komfortabelste Weg eine Datenbank anzusprechen. Die angezeigten Tabellen wurden per
        Drag’n’Drop im Schema platziert. VS 2008 erkennt automatisch die Fremdschlüsselbeziehungen in der
        Datenbank und generiert die später verwendeten Klassen.
       Database.cs, enthält die selbst geschriebenen Methoden, die später in der Homepage für die Verarbeitung der
        Daten nötig sind.

Homepage
Das Projekt Homepage referenziert das Projekt BusinessLogic und kann somit die dort definierten Klassen und
Methoden benutzen. Im Ordner bin liegt deshalb auch die Datei „BusinessLogic.dll“.


Erstellen der Webanwendung

Anlegen einer Website mit Masterpage
       zunächst das ZIP-Archiv „Vorlage_(Linq-to-SQL).zip“ in einen beliebigen Ordner entpacken
       dann in VS: File  Open  Project  “Tutorial.sln”

Nun wollen wir eine Masterpage anlegen. Masterpages dienen als Designtemplate, Elemente die auf jeder Seite
vorkommen, sollten am besten dort eingebunden werden (z.B. Header, Footer, CSS)

       Im Solution Explorer (Rechtklick auf „Homepage“): Add New Item  Master Page

In der Masterpage liegt folgendes Element:

<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>

Innerhalb des Contentplaceholder platzieren später alle Seiten, die diese Masterpage verwenden, ihren eigenen
Code/Inhalt.
Wir wollen nun eine globale Überschrift hinzufügen:

      Aus der Toolbar ziehen wir ein Literal vor den Contentplaceholder (den Text könnten wir auch so (ohne
       Verwendung eines Literals in den Quellcode schreiben, dadurch wäre die Seite aber nicht mehr
       mehrsprachenfähig), da wir eine Überschrift wollen, umschließen wir das Literal noch mit <h1>…</h1>
      Wir vergeben noch eine passendere ID, z.B. headerLiteral und geben eine Überschrift ein, das Ergebnis sieht
       etwa so aus:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs"
Inherits="MasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <link rel="stylesheet" type="text/css" href="css/format.css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
      <h1>
            <asp:Literal ID="headerLiteral" runat="server">ASP.NET Tutorial</asp:Literal>
      </h1>
      <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
      </asp:contentplaceholder>
    </div>
    </form>
</body>
</html>

Anlegen einer Startseite
      Als ersten legen wir eine Startseite an. Diese heißt Default.aspx.
      Im Solution Explorer (im Homepage-Projekt): Add New Item  …
      In den ContentPlaceHolder ziehen wir aus der Toolbox einen Hyperlink, vergeben wieder eine passende ID und
       den Text „Zum Gästebuch“, zudem setzen wir NavigateUrl="Guestbook.aspx", fertig sieht das so aus:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" Title="Startseite" %>

<asp:Content ID="mainContent" ContentPlaceHolderID="mainContentPlaceHolder"
Runat="Server">
    <asp:HyperLink ID="guestbookHyperLink" runat="server"
NavigateUrl="Guestbook.aspx">Zum Gästebuch</asp:HyperLink>
</asp:Content>

Anlegen der weiteren Seiten
      Das Anlegen der Datei „Guestbook.aspx“ erfolgt analog zur „Default.aspx“
      Zusätzlich legen wir noch die Dateien „Login.aspx“ und „Register.aspx“ an

Passwortschutz einrichten
      Die Datei „Login.aspx“ bauen wir folgendermaßen auf:

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

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    <asp:Login ID="mainLogin" runat="server" FailureText="Login fehlgeschlagen."
DestinationPageUrl="~/Default.aspx">
        <LayoutTemplate>
            <asp:Textbox id="UserName" runat="server" maxlength="50" width="200"
Text="Benutzername" />
            <asp:RequiredFieldValidator ID="usernameRequiredFieldValidator"
runat="server" ErrorMessage="Bitte Benutzernamen eingeben."
                ControlToValidate="Username" ForeColor="#cc0000" ValidationGroup="login"
InitialValue="Benutzername"></asp:RequiredFieldValidator><br />
            <br />
            <asp:TextBox ID="Password" runat="server" Width="200" MaxLength="50"
TextMode="Password"></asp:TextBox>
            <asp:RequiredFieldValidator ID="passwordRequiredFieldValidator"
runat="server" ErrorMessage="Bitte Passwort eingeben."
                ControlToValidate="Password" ForeColor="#cc0000"
ValidationGroup="login"></asp:RequiredFieldValidator><br />
            <br />
            <asp:CheckBox ID="RememberMe" runat="server" ValidationGroup="login"
Checked="True"
                Text="Login speichern" />
            <br />
            <br />
            <asp:Button ID="LoginButton" runat="server" Text="Einloggen"
CommandName="Login"
                ValidationGroup="login" />
            <asp:Label ID="FailureText" runat="server" ForeColor="#cc0000"></asp:Label>
        </LayoutTemplate>
    </asp:Login>
    <br />
    <br />
    <h2>
        <asp:Literal ID="header2Literal" runat="server">Zur Registrierung</asp:Literal>
    </h2>
    <asp:HyperLink ID="registerHyperLink" runat="server"
NavigateUrl="Register.aspx">Registrieren</asp:HyperLink>
</asp:Content>

      Alternativ kann man auch das Login-Control aus der Toolbox verwenden
      Um nun das Gästebuch nur für registrierte Benutzer sichtbar zu machen, ist folgender Code in der Web.config
       (im Abschnitt <configuration> … </configuration>, hinter <configSections> … </configSections>) einzutragen:

<location path="Guestbook.aspx">
    <system.web>
      <authorization>
        <deny users="?"/>
      </authorization>
    </system.web>
</location>

      Mit dem „?“ werden alle unangemeldeten User geblockt, alternativ ist es auch möglich nur bestimmte Gruppen
       zulassen bzw. sperren, das geht mit:
           o <allow roles="Admin"/>
           o <deny roles="Editor, User"/>
      Damit die ASP.NET-Anwendung die Nutzerdaten finden kann, muss noch folgender Code in der Web.config (im
       Abschnitt <system.web> … </system.web>) eingetragen werden:

<authentication mode="Forms">
      <forms name=".ASPXAUTH" loginUrl="Login.aspx" protection="Validation"
timeout="999999"/>
</authentication>
<roleManager defaultProvider="TutorialRoleProvider" enabled="true">
   <providers>
      <add name="TutorialRoleProvider" type="Tutorial.Auth.TutorialRoleProvider"/>
   </providers>
</roleManager>
<membership defaultProvider="TutorialMembershipProvider" userIsOnlineTimeWindow="15">
   <providers>
      <add name="TutorialMembershipProvider"
   type="Tutorial.Auth.TutorialMembershipProvider" enablePasswordRetrieval="false"
   enablePasswordReset="false" requiresQuestionAndAnswer="false" applicationName="/"
   requiresUniqueEmail="true" passwordFormat="MD5" description="Stores and retrieves
   membership data from SQL Server"/>
   </providers>
</membership>

       Die Zeile <authentication mode="Windows" /> muss dabei gelöscht werden.

      Die im ZIP-Archiv enthaltenen Dateien
           o App_Code/TutorialMembershipProvider.cs
           o App_Code/TutorialRoleProvider.cs
       implementieren jeweils ein von Mircosoft vorgegebenes Interface, das sich um die Benutzerdaten kümmert.
       Jedoch müssen für unsere Zwecke nur wenige Methoden implementiert werden.
       Bei weiteren Projekten können diese Dateien, entsprechend angepasst, weiterverwendet werden.
Registrieren von Benutzern
           In der Datei „Register.aspx“ platzieren wir die folgenden Elemente:
                o zwei Textboxen (nameTextBox, passwordTextBox)
                o eine DropDownList (rolesDropDownList)
                o einen Button (submitButton)

           Beim submitButton setzen wir das Attribut OnClick="submitButton_Click"
           Nun kommen wir zum ersten Mal mit einer sog. Code-Behind-Datei in Berühung, dort ist die eigentliche Logik
            der Seite hinterlegt, in den ASPX-Seiten sind nur die Designelemente, dadurch wird eine Code von Design sauber
            getrennt
           In der Datei „Register.aspx.cs“ fügen wir folgendes ein:

using Tutorial.Auth;

public partial class Register : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            foreach (Role role in Enum.GetValues(typeof(Role)))
            {
                rolesDropDownList.Items.Add(role.ToString());
            }
            rolesDropDownList.DataBind();
        }
    }

    protected void submitButton_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            Tutorial.BusinessLogic.Database.User.InsertUser(nameTextBox.Text,
passwordTextBox.Text, rolesDropDownList.SelectedValue);

                    successLiteral.Visible = true;
                    guestbookHyperLink.Visible = true;
                    dataDiv.Visible = false;
              }
        }
}
            Die Methode Page_Load(object sender, EventArgs e)wird beim Laden der Seite ausgeführt, dabei
            wird die rolesDropDownList mit Inhalten gefüllt. Allerdings nur, wenn es sich nicht um einen Postback
            handelt.
            Die Methode submitButton_Click(object sender, EventArgs e)wird beim Drücken unseres Buttons
            aufgerufen. Sie liest die Benutzereingaben auf der Seite aus und legt einen neuen Benutzer auf.

Anlegen des Gästebuchs
           Das Gästebuch funktioniert ähnlich wie das Registrieren; wir verwenden den folgenden Code für die Datei
            „Guestbook.aspx“:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
    CodeFile="Guestbook.aspx.cs" Inherits="Guestbook" Title="Gästebuch" %>

<asp:Content ID="mainContent" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    <asp:LinqDataSource ID="guestbookLinqDataSource" runat="server"
ContextTypeName="Tutorial.BusinessLogic.Database.DatabaseDataContext"
        OrderBy="date desc" TableName="GuestbookEntries"
        EnableDelete="True">
    </asp:LinqDataSource>
    <h2>
        <asp:Literal ID="header1Literal" runat="server">Eintrag verfassen</asp:Literal>
    </h2>
    <asp:TextBox ID="commentTextBox" runat="server" Rows="5" TextMode="MultiLine"
Width="300"
        Text="Eintrag" />
    <asp:RequiredFieldValidator ID="commentRequiredFieldValidator" runat="server"
ErrorMessage="Bitte Eintrag ausfüllen."
        ControlToValidate="commentTextBox" ForeColor="#cc0000" InitialValue="Eintrag"
        ValidationGroup="guestbook">
    </asp:RequiredFieldValidator>
    <br />
    <br />
    <asp:Button ID="submitButton" runat="server" Text="Abschicken"
OnClick="submitButton_Click"
        ValidationGroup="guestbook" />
            <asp:UpdateProgress ID="submitUpdateProgress" runat="server">
                <ProgressTemplate>
                    <br />
                    <img src="gx/indicator.gif" alt="Aktualisiere" />
                </ProgressTemplate>
            </asp:UpdateProgress>
            <br />
            <br />
            <asp:ListView ID="guestBookListView" runat="server" DataKeyNames="entryID"
DataSourceID="guestbookLinqDataSource">
                <LayoutTemplate>
                    <asp:PlaceHolder runat="server"
ID="itemPlaceholder"></asp:PlaceHolder>
                </LayoutTemplate>
                <ItemTemplate>
                    <%# "Name: " + ((string)Eval("User.name")) %>
                    <br />
                    <%# "Kommentar: " + ((string)Eval("comment")) %>
                    <br />
                    <%# ((DateTime)Eval("date")).ToString("dd.MM.yyyy") %>
                    <br />
                    <br />
                    <div id="adminDiv" runat="server" visible='<%# IsAdmin %>'>
                        <asp:LinkButton ID="deleteGuestbookEntryLinkButton"
runat="server" CommandName="Delete"
                            Text="Eintrag löschen"></asp:LinkButton>
                    </div>
                </ItemTemplate>
                <ItemSeparatorTemplate>
                    <br />
                    <hr />
                    <br />
                </ItemSeparatorTemplate>
            </asp:ListView>
            <br />
            <br />
            <asp:DataPager ID="guestbookDataPager" runat="server"
PagedControlID="guestBookListView"
                PageSize="3">
                <Fields>
                    <asp:NextPreviousPagerField ButtonType="Button"
ShowNextPageButton="False" ShowPreviousPageButton="False" />
                    <asp:NumericPagerField />
                    <asp:NextPreviousPagerField ButtonType="Button"
ShowNextPageButton="False" ShowPreviousPageButton="False" />
                </Fields>
            </asp:DataPager>
</asp:Content>

      Hier sind folgende Elemente vorhanden:
          o TextBox und Button zum Schreiben eines neuen Eintrags
          o Eine sogenannter ListView, der vorhandene Einträge darstellt
          o LinqDataSource aus der die ListView ihre Daten bezieht
            o   innerhalb des ListView gibt es einen Abschnitt adminDiv, dieser ist nur Administratoren sichtbar, um
                sicherzustellen, das wirklich nur Administratoren die Löschfunktion aufrufen muss man dies eigentlich
                auch in der Code-Behind-Datei noch überprüfen, worauf ich in diesem Tutorial jedoch verzichtet habe.
                Macht man dies nicht, so kann ein böswilliger Anwender durch einen entsprechenden Aufruf beliebige
                Einträge löschen, das bloße Unsichtbarmachen reicht hier nicht.
            o   Einen DataPager, dieser sorgt dafür, dass immer 3 Einträge des Gästebuchs sichtbar sind
                 durch einen entsprechenden Aufruf beliebige Einträge löschen, das bloße Unsichtbarmachen reicht hier
                nicht.

        In der Datei „Guestbook.aspx.cs“ fügen wir folgendes ein:

using System;
using System.Web.UI;
using Tutorial.BusinessLogic.Database;

public partial class Guestbook : ExtendedPage
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            guestBookListView.DataBind();
        }
    }

        protected void submitButton_Click(object sender, EventArgs e)
        {
            if (Page.IsValid)
            {
                GuestbookEntry.InsertGuestbookEntry(UserID, commentTextBox.Text);
                guestBookListView.DataBind();
            }
        }
}
Damit wird erreicht, dass Gästebucheinträge gespeichert werden können, das Löschen geschieht implizit über die
LinqDataSource.

Gästebuch um Ajax Funktionalität erweitern
        Das Gästebuch kann leicht um Ajax-Funktionalität erweitert werden:
             o Hinzufügen eines ScriptManager an beliebiger Stelle im Code, jedoch vor dem noch folgenden
                UpdatePanel:
                <asp:ScriptManager ID="guestbookScriptManager" runat="server" />
            o   Umschließen der ListView mit dem folgendem Code:

<asp:UpdatePanel ID="guestbookUpdatePanel" runat="server">
      <ContentTemplate>

         … bisheriger Code …

      </ContentTemplate>
</asp:UpdatePanel>

Nun laufen alle Requests innerhalb des UpdatePanels asynchron ab.

Lokalisierung der ASP.NET-Anwendung
Da wir alle statischen Texte auf der Homepage konsequent in Literals bzw. Labels gesetzt haben, ist die Lokalisierung
nun denkbar einfach. Man öffnet die entsprechende ASPX-Seite geht in den Design-Modus und wählt im Menü:

        Tools  Generate Local Resource
        Im Ordner App_ LocalResources liegt nun die entsprechende Datei
        Soll nun in eine andere Sprache übersetzt werden, so muss nur diese Datei kopiert und übersetzt werden
Aufpassen muss man nur, wenn man Text in den Code-Behind-Dateien setzt. Dann müssen die entsprechenden Texte
ebenfalls in die Resource-Datei eintragen werden und man kann entsprechend darauf zugreifen.

Testen der Anwendung
Nachdem wir nun soweit fertig sind, können wir die Anwendung testen. Dazu drücken wir einfach F5 in Visual Studio.

Folgende Benutzer sind bereits vorhanden und können zum Testen verwendet werden: Admin, Editor1, Editor2
Passwort ist jeweils: 12345

Bei Fehlern oder als Referenz kann man in der vollständigen Anwendung nachsehen, die ebenfalls als ZIP-Datei vorliegt.

In der vollständigen Anwendung sind auch noch zusätzliche Features, wie ein Logout-Button usw. enthalten.


Was muss bei einer „richtigen“ ASP.NET noch beachtet werden?

Anmerkungen zu diesem Tutorial
Das Tutorial ist relativ knapp gehalten, es wird nicht alles bis ins Detail erläutert.
Das Ziel ist es, einen Einblick in die Arbeit mit ASP.NET zu geben. Nicht alle Dateien, insbesondere die Buinesslogik,
wurden erläutert, hier sollte man selber einen Blick in den fertigen Code werfen.

Allgemeines
Bei einer vollständigen Anwendung müssen u.a. noch folgende Dinge zusätzlich gemacht werden:

      Benutzereingaben auf Fehler prüfen (Länge von Texteingaben, kein HTML-Code bei Gästebüchern, kein
       Benutzername doppelt in der Datenbank, usw.)
      Passwörter müssen verschlüsselt in der Datenbank gespeichert werden
      Da es sich um eine Webanwendung handelt und somit alle Befehle auch „von Hand“ per http an die Seite
       geschickt werden können, muss auch in den Code-Behind-Dateien ggf. überprüft werden, ob etwa ein Admin die
       entsprechende Funktion aufruft, das bloße Ausblenden entsprechender Buttons auf den ASPX-Seiten reicht hier
       nicht aus.
      Fehlerbehandlung
Anhang

Die Datenbank
Die Datenbank ist bereits fertig, wer die Datenbank selber anlegen will, muss folgendermaßen vorgehen:

      Im Solution Explorer rechts auf unser Projekt klicken: Add ASP.NET Folder  App_Data
      Rechtsklick auf den neuen Ordner: Add New Item




      Im Server Explorer müssen wir die 3 folgenden Tabellen anlegen (Rechtsklick auf Table  Add new Table):

       Dabei muss insbesondere bei „roles“ auf den/die Primärschlüssel geachtet werden (entsprechende Werte
       markieren und dann nach Rechtsklick „Set primary key“ auswählen)

           o   users




           o   roles




           o   guestbook
   Nun müssen noch die Fremdschlüsselbeziehungen angelegt werden, was über folgende SQL-Statements möglich
    ist:

    ALTER TABLE [roles] ADD CONSTRAINT [ReferenceUser] FOREIGN KEY([userID])
    REFERENCES [users] ([userID])
    ON DELETE CASCADE

    ALTER TABLE [guestbook] ADD CONSTRAINT [ReferenceUser] FOREIGN KEY([userID])
    REFERENCES [users] ([userID])
    ON DELETE CASCADE