Mitgliedschaft und Verwaltung
von Erik Reitan
Diese Tutorialreihe vermittelt Ihnen die Grundlagen zum Erstellen einer ASP.NET Web Forms-Anwendung mit ASP.NET 4.5 und Microsoft Visual Studio Express 2013 für Web. Ein Visual Studio 2013-Projekt mit C#-Quellcode ist für diese Tutorialreihe verfügbar.
In diesem Tutorial erfahren Sie, wie Sie die Wingtip Toys-Beispielanwendung aktualisieren, um eine benutzerdefinierte Rolle hinzuzufügen und ASP.NET Identität zu verwenden. Außerdem wird gezeigt, wie Sie eine Verwaltungsseite implementieren, auf der der Benutzer mit einer benutzerdefinierten Rolle Produkte zur Website hinzufügen und daraus entfernen kann.
ASP.NET Identity ist das Mitgliedschaftssystem, das zum Erstellen ASP.NET Webanwendung verwendet wird und in ASP.NET 4.5 verfügbar ist. ASP.NET Identity wird in der Projektvorlage Visual Studio 2013 Web Forms sowie in den Vorlagen für ASP.NET MVC, ASP.NET-Web-API und ASP.NET Single Page Application verwendet. Sie können das ASP.NET Identity-System auch mithilfe von NuGet speziell installieren, wenn Sie mit einer leeren Webanwendung beginnen. In dieser Tutorialreihe verwenden Sie jedoch die Web Forms projecttemplate, die das ASP.NET Identity-System enthält. ASP.NET Identity erleichtert die Integration von benutzerspezifischen Profildaten in Anwendungsdaten. Außerdem können Sie im ASP.NET Identity das Persistenzmodell für die Benutzerprofile in Ihrer Anwendung auswählen. Sie können die Daten in einer SQL Server-Datenbank oder einem anderen Datenspeicher speichern, einschließlich NoSQL-Datenspeichern wie Windows Azure Storage-Tabellen.
Dieses Tutorial baut auf dem vorherigen Tutorial mit dem Titel "Checkout and Payment with PayPal" in der Wingtip Toys Tutorial Series auf.
Sie lernen Folgendes:
- Verwenden von Code zum Hinzufügen einer benutzerdefinierten Rolle und eines Benutzers zur Anwendung.
- Hier erfahren Sie, wie Sie den Zugriff auf den Verwaltungsordner und die Seite einschränken.
- Hier erfahren Sie, wie Sie die Navigation für den Benutzer bereitstellen, der zur benutzerdefinierten Rolle gehört.
- Verwenden der Modellbindung zum Auffüllen eines DropDownList-Steuerelements mit Produktkategorien.
- Hier erfahren Sie, wie Sie eine Datei mithilfe des FileUpload-Steuerelements in die Webanwendung hochladen.
- Verwenden von Validierungssteuerelementen zum Implementieren der Eingabeüberprüfung
- Hinzufügen und Entfernen von Produkten aus der Anwendung
Diese Features sind im Tutorial enthalten:
- ASP.NET Identity
- Konfiguration und Autorisierung
- Modellbindung
- Unauffällige Validierung
ASP.NET Web Forms bietet Mitgliedschaftsfunktionen. Mit der Standardvorlage verfügen Sie über integrierte Mitgliedschaftsfunktionen, die Sie sofort verwenden können, wenn die Anwendung ausgeführt wird. In diesem Tutorial erfahren Sie, wie Sie ASP.NET Identity verwenden, um eine benutzerdefinierte Rolle hinzuzufügen und dieser Rolle einen Benutzer zuzuweisen. Sie erfahren, wie Sie den Zugriff auf den Verwaltungsordner einschränken. Sie fügen dem Verwaltungsordner eine Seite hinzu, die es einem Benutzer mit einer benutzerdefinierten Rolle ermöglicht, Produkte hinzuzufügen und zu entfernen sowie nach dem Hinzufügen eine Vorschau eines Produkts anzuzeigen.
Hinzufügen einer benutzerdefinierten Rolle
Mit ASP.NET Identity können Sie eine benutzerdefinierte Rolle hinzufügen und dieser Rolle mithilfe von Code einen Benutzer zuweisen.
Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf den Ordner Logic, und erstellen Sie eine neue Klasse.
Nennen Sie die neue Klasse RoleActions.cs.
Ändern Sie den Code so, dass er wie folgt angezeigt wird:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WingtipToys.Logic { internal class RoleActions { } }
Öffnen Sie in Projektmappen-Explorer die Datei Global.asax.cs.
Ändern Sie die Datei Global.asax.cs , indem Sie den gelb hervorgehobenen Code hinzufügen, sodass er wie folgt angezeigt wird:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Optimization; using System.Web.Routing; using System.Web.Security; using System.Web.SessionState; using System.Data.Entity; using WingtipToys.Models; using WingtipToys.Logic; namespace WingtipToys { public class Global : HttpApplication { void Application_Start(object sender, EventArgs e) { // Code that runs on application startup RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // Initialize the product database. Database.SetInitializer(new ProductDatabaseInitializer()); // Create the custom role and user. RoleActions roleActions = new RoleActions(); roleActions.AddUserAndRole(); } } }
Beachten Sie, dass
AddUserAndRole
rot unterstrichen ist. Doppelklicken Sie auf den Code AddUserAndRole.
Der Buchstabe "A" am Anfang der hervorgehobenen Methode wird unterstrichen.Zeigen Sie auf den Buchstaben "A", und klicken Sie auf die Benutzeroberfläche, mit der Sie einen Methodenstub für die
AddUserAndRole
Methode generieren können.Klicken Sie auf die Option mit dem Titel:
Generate method stub for "AddUserAndRole" in "WingtipToys.Logic.RoleActions"
Öffnen Sie die Datei RoleActions.cs aus dem Ordner Logic .
DieAddUserAndRole
-Methode wurde der Klassendatei hinzugefügt.Ändern Sie die Datei RoleActions.cs , indem Sie die
NotImplementedException
entfernen und den gelb hervorgehobenen Code hinzufügen, sodass er wie folgt angezeigt wird:using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Web; using WingtipToys.Models; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; namespace WingtipToys.Logic { internal class RoleActions { internal void AddUserAndRole() { // Access the application context and create result variables. Models.ApplicationDbContext context = new ApplicationDbContext(); IdentityResult IdRoleResult; IdentityResult IdUserResult; // Create a RoleStore object by using the ApplicationDbContext object. // The RoleStore is only allowed to contain IdentityRole objects. var roleStore = new RoleStore<IdentityRole>(context); // Create a RoleManager object that is only allowed to contain IdentityRole objects. // When creating the RoleManager object, you pass in (as a parameter) a new RoleStore object. var roleMgr = new RoleManager<IdentityRole>(roleStore); // Then, you create the "canEdit" role if it doesn't already exist. if (!roleMgr.RoleExists("canEdit")) { IdRoleResult = roleMgr.Create(new IdentityRole { Name = "canEdit" }); } // Create a UserManager object based on the UserStore object and the ApplicationDbContext // object. Note that you can create new objects and use them as parameters in // a single line of code, rather than using multiple lines of code, as you did // for the RoleManager object. var userMgr = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)); var appUser = new ApplicationUser { UserName = "canEditUser@wingtiptoys.com", Email = "canEditUser@wingtiptoys.com" }; IdUserResult = userMgr.Create(appUser, ConfigurationManager.AppSettings["AppUserPasswordKey"]); // If the new "canEdit" user was successfully created, // add the "canEdit" user to the "canEdit" role. if (!userMgr.IsInRole(userMgr.FindByEmail("canEditUser@wingtiptoys.com").Id, "canEdit")) { IdUserResult = userMgr.AddToRole(userMgr.FindByEmail("canEditUser@wingtiptoys.com").Id, "canEdit"); } } } }
Mit dem obigen Code wird zunächst ein Datenbankkontext für die Mitgliedschaftsdatenbank eingerichtet. Die Mitgliedschaftsdatenbank wird auch als MDF-Datei im Ordner App_Data gespeichert. Sie können diese Datenbank anzeigen, sobald sich der erste Benutzer bei dieser Webanwendung angemeldet hat.
Hinweis
Wenn Sie die Mitgliedschaftsdaten zusammen mit den Produktdaten speichern möchten, können Sie denselben DbContext verwenden, den Sie zum Speichern der Produktdaten im obigen Code verwendet haben.
Der interne Schlüsselwort (keyword) ist ein Zugriffsmodifizierer für Typen (z. B. Klassen) und Typmember (z. B. Methoden oder Eigenschaften). Auf interne Typen oder Member kann nur in Dateien zugegriffen werden, die in derselben Assembly (.dll Datei) enthalten sind. Wenn Sie Ihre Anwendung erstellen, wird eine Assemblydatei (.dll) erstellt, die den Code enthält, der beim Ausführen der Anwendung ausgeführt wird.
Ein RoleStore
-Objekt, das die Rollenverwaltung bereitstellt, wird basierend auf dem Datenbankkontext erstellt.
Hinweis
Beachten Sie, dass beim Erstellen des RoleStore
Objekts ein generischer IdentityRole
Typ verwendet wird. Dies bedeutet, dass nur RoleStore
-Objekte enthalten IdentityRole
dürfen. Auch durch die Verwendung von Generics werden Ressourcen im Arbeitsspeicher besser behandelt.
Als Nächstes wird das RoleManager
-Objekt basierend auf dem RoleStore
Objekt erstellt, das Sie gerade erstellt haben. das RoleManager
-Objekt macht die rollenbezogene API verfügbar, die zum automatischen Speichern von Änderungen an verwendet RoleStore
werden kann. Die RoleManager
darf nur Objekte enthalten IdentityRole
, da der Code den <IdentityRole>
generischen Typ verwendet.
Sie rufen die RoleExists
-Methode auf, um zu bestimmen, ob die Rolle "canEdit" in der Mitgliedschaftsdatenbank vorhanden ist. Wenn dies nicht der Grund ist, erstellen Sie die Rolle.
Das Erstellen des UserManager
Objekts scheint komplizierter als das RoleManager
Steuerelement zu sein, es ist jedoch fast identisch. Sie ist nur in einer Zeile und nicht in mehreren Zeilen codiert. Hier wird der Parameter, den Sie übergeben, als neues Objekt instanziiert, das in der Klammer enthalten ist.
Als Nächstes erstellen Sie den Benutzer "canEditUser", indem Sie ein neues ApplicationUser
-Objekt erstellen. Wenn Sie den Benutzer dann erfolgreich erstellt haben, fügen Sie den Benutzer der neuen Rolle hinzu.
Hinweis
Die Fehlerbehandlung wird während des Tutorials "ASP.NET Fehlerbehandlung" weiter unten in dieser Tutorialreihe aktualisiert.
Beim nächsten Start der Anwendung wird der Benutzer mit dem Namen "canEditUser" als Rolle "canEdit" der Anwendung hinzugefügt. Später in diesem Tutorial melden Sie sich als "canEditUser"-Benutzer an, um zusätzliche Funktionen anzuzeigen, die Sie während dieses Tutorials hinzugefügt haben. Api-Details zu ASP.NET Identity finden Sie im Microsoft.AspNet.Identity-Namespace. Weitere Informationen zum Initialisieren des ASP.NET Identity-Systems finden Sie unter AspnetIdentitySample.
Einschränken des Zugriffs auf die Verwaltungsseite
Die Wingtip Toys-Beispielanwendung ermöglicht es sowohl anonymen als auch angemeldeten Benutzern, Produkte anzuzeigen und zu kaufen. Der angemeldete Benutzer mit der benutzerdefinierten Rolle "canEdit" kann jedoch auf eine eingeschränkte Seite zugreifen, um Produkte hinzuzufügen und zu entfernen.
Hinzufügen eines Verwaltungsordners und einer Seite
Als Nächstes erstellen Sie einen Ordner namens Admin für den Benutzer "canEditUser", der zur benutzerdefinierten Rolle der Wingtip Toys-Beispielanwendung gehört.
- Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf den Projektnamen (Wingtip Toys), und wählen Sie Hinzufügen ->Neuer Ordner aus.
- Benennen Sie den neuen Ordner Admin.
- Klicken Sie mit der rechten Maustaste auf den Ordner Admin, und wählen Sie dann Hinzufügen –>Neues Element aus.
Das Dialogfeld Neues Element hinzufügen wird angezeigt. - Wählen Sie links die Gruppe Visual C#->Web templates aus. Wählen Sie in der mittleren Liste Webformular mit Gestaltungsvorlage aus, nennen Sie es AdminPage.aspx, und wählen Sie dann Hinzufügen aus.
- Wählen Sie die Datei Site.Master als master Seite aus, und klicken Sie dann auf OK.
Hinzufügen einer Web.config-Datei
Indem Sie dem Ordner Admin eine Web.config-Datei hinzufügen, können Sie den Zugriff auf die im Ordner enthaltene Seite einschränken.
Klicken Sie mit der rechten Maustaste auf den Ordner Admin, und wählen Sie Hinzufügen –>Neues Element aus.
Das Dialogfeld Neues Element hinzufügen wird angezeigt.Wählen Sie in der Liste der Visual C#-Webvorlagen in der mittleren Liste Webkonfigurationsdateiaus, übernehmen Sie den Standardnamen Web.config, und wählen Sie dann Hinzufügen aus.
Ersetzen Sie den vorhandenen XML-Inhalt in der Datei Web.config durch den folgenden Code:
<?xml version="1.0"?> <configuration> <system.web> <authorization> <allow roles="canEdit"/> <deny users="*"/> </authorization> </system.web> </configuration>
Speichern Sie die Datei Web.config . Die Web.config-Datei gibt an, dass nur Benutzer, die der Rolle "canEdit" der Anwendung angehören, auf die im Ordner Admin enthaltene Seite zugreifen können.
Einschließen der benutzerdefinierten Rollennavigation
Damit der Benutzer der benutzerdefinierten Rolle "canEdit" zum Verwaltungsabschnitt der Anwendung navigieren kann, müssen Sie einen Link zur Seite Site.Master hinzufügen. Nur Benutzer, die der Rolle "canEdit" angehören, können den link Admin anzeigen und auf den Verwaltungsabschnitt zugreifen.
Suchen Sie in Projektmappen-Explorer die Seite Site.Master, und öffnen Sie sie.
Um einen Link für den Benutzer der Rolle "canEdit" zu erstellen, fügen Sie das in Gelb hervorgehobene Markup dem folgenden ungeordneten Listenelement
<ul>
hinzu, damit die Liste wie folgt angezeigt wird:<ul class="nav navbar-nav"> <li><a runat="server" id="adminLink" visible="false" href="~/Admin/AdminPage">Admin</a></li> <li><a runat="server" href="~/">Home</a></li> <li><a runat="server" href="~/About">About</a></li> <li><a runat="server" href="~/Contact">Contact</a></li> <li><a runat="server" href="~/ProductList">Products</a></li> <li><a runat="server" href="~/ShoppingCart" ID="cartCount"> </a></li> </ul>
Öffnen Sie die Datei Site.Master.cs . Machen Sie den Admin Link nur für den Benutzer "canEditUser" sichtbar, indem Sie dem
Page_Load
Handler den gelb hervorgehobenen Code hinzufügen. DerPage_Load
Handler wird wie folgt angezeigt:protected void Page_Load(object sender, EventArgs e) { if (HttpContext.Current.User.IsInRole("canEdit")) { adminLink.Visible = true; } }
Wenn die Seite geladen wird, überprüft der Code, ob der angemeldete Benutzer die Rolle "canEdit" hat. Wenn der Benutzer zur Rolle "canEdit" gehört, wird das span-Element, das den Link zur Seite AdminPage.aspx (und folglich den Link innerhalb der Spanne) enthält, sichtbar gemacht.
Aktivieren der Produktverwaltung
Bisher haben Sie die Rolle "canEdit" erstellt und einen Benutzer "canEditUser", einen Verwaltungsordner und eine Verwaltungsseite hinzugefügt. Sie haben Zugriffsrechte für den Verwaltungsordner und die Seite festgelegt und der Anwendung einen Navigationslink für den Benutzer der Rolle "canEdit" hinzugefügt. Als Nächstes fügen Sie der Seite AdminPage.aspx Markup und Code zur CodeBehind-Datei AdminPage.aspx.cs hinzu, die es dem Benutzer mit der Rolle "canEdit" ermöglicht, Produkte hinzuzufügen und zu entfernen.
Öffnen Sie in Projektmappen-Explorer die Datei AdminPage.aspx aus dem Ordner Admin.
Ersetzen Sie das vorhandene Markup durch Folgendes:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="AdminPage.aspx.cs" Inherits="WingtipToys.Admin.AdminPage" %> <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server"> <h1>Administration</h1> <hr /> <h3>Add Product:</h3> <table> <tr> <td><asp:Label ID="LabelAddCategory" runat="server">Category:</asp:Label></td> <td> <asp:DropDownList ID="DropDownAddCategory" runat="server" ItemType="WingtipToys.Models.Category" SelectMethod="GetCategories" DataTextField="CategoryName" DataValueField="CategoryID" > </asp:DropDownList> </td> </tr> <tr> <td><asp:Label ID="LabelAddName" runat="server">Name:</asp:Label></td> <td> <asp:TextBox ID="AddProductName" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" Text="* Product name required." ControlToValidate="AddProductName" SetFocusOnError="true" Display="Dynamic"></asp:RequiredFieldValidator> </td> </tr> <tr> <td><asp:Label ID="LabelAddDescription" runat="server">Description:</asp:Label></td> <td> <asp:TextBox ID="AddProductDescription" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" Text="* Description required." ControlToValidate="AddProductDescription" SetFocusOnError="true" Display="Dynamic"></asp:RequiredFieldValidator> </td> </tr> <tr> <td><asp:Label ID="LabelAddPrice" runat="server">Price:</asp:Label></td> <td> <asp:TextBox ID="AddProductPrice" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" Text="* Price required." ControlToValidate="AddProductPrice" SetFocusOnError="true" Display="Dynamic"></asp:RequiredFieldValidator> <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" Text="* Must be a valid price without $." ControlToValidate="AddProductPrice" SetFocusOnError="True" Display="Dynamic" ValidationExpression="^[0-9]*(\.)?[0-9]?[0-9]?$"></asp:RegularExpressionValidator> </td> </tr> <tr> <td><asp:Label ID="LabelAddImageFile" runat="server">Image File:</asp:Label></td> <td> <asp:FileUpload ID="ProductImage" runat="server" /> <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" Text="* Image path required." ControlToValidate="ProductImage" SetFocusOnError="true" Display="Dynamic"></asp:RequiredFieldValidator> </td> </tr> </table> <p></p> <p></p> <asp:Button ID="AddProductButton" runat="server" Text="Add Product" OnClick="AddProductButton_Click" CausesValidation="true"/> <asp:Label ID="LabelAddStatus" runat="server" Text=""></asp:Label> <p></p> <h3>Remove Product:</h3> <table> <tr> <td><asp:Label ID="LabelRemoveProduct" runat="server">Product:</asp:Label></td> <td><asp:DropDownList ID="DropDownRemoveProduct" runat="server" ItemType="WingtipToys.Models.Product" SelectMethod="GetProducts" AppendDataBoundItems="true" DataTextField="ProductName" DataValueField="ProductID" > </asp:DropDownList> </td> </tr> </table> <p></p> <asp:Button ID="RemoveProductButton" runat="server" Text="Remove Product" OnClick="RemoveProductButton_Click" CausesValidation="false"/> <asp:Label ID="LabelRemoveStatus" runat="server" Text=""></asp:Label> </asp:Content>
Öffnen Sie als Nächstes die CodeBehind-Datei AdminPage.aspx.cs , indem Sie mit der rechten Maustaste auf adminPage.aspx und dann auf Code anzeigen klicken.
Ersetzen Sie den vorhandenen Code in der CodeBehind-Datei AdminPage.aspx.cs durch den folgenden Code:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using WingtipToys.Models; using WingtipToys.Logic; namespace WingtipToys.Admin { public partial class AdminPage : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string productAction = Request.QueryString["ProductAction"]; if (productAction == "add") { LabelAddStatus.Text = "Product added!"; } if (productAction == "remove") { LabelRemoveStatus.Text = "Product removed!"; } } protected void AddProductButton_Click(object sender, EventArgs e) { Boolean fileOK = false; String path = Server.MapPath("~/Catalog/Images/"); if (ProductImage.HasFile) { String fileExtension = System.IO.Path.GetExtension(ProductImage.FileName).ToLower(); String[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg" }; for (int i = 0; i < allowedExtensions.Length; i++) { if (fileExtension == allowedExtensions[i]) { fileOK = true; } } } if (fileOK) { try { // Save to Images folder. ProductImage.PostedFile.SaveAs(path + ProductImage.FileName); // Save to Images/Thumbs folder. ProductImage.PostedFile.SaveAs(path + "Thumbs/" + ProductImage.FileName); } catch (Exception ex) { LabelAddStatus.Text = ex.Message; } // Add product data to DB. AddProducts products = new AddProducts(); bool addSuccess = products.AddProduct(AddProductName.Text, AddProductDescription.Text, AddProductPrice.Text, DropDownAddCategory.SelectedValue, ProductImage.FileName); if (addSuccess) { // Reload the page. string pageUrl = Request.Url.AbsoluteUri.Substring(0, Request.Url.AbsoluteUri.Count() - Request.Url.Query.Count()); Response.Redirect(pageUrl + "?ProductAction=add"); } else { LabelAddStatus.Text = "Unable to add new product to database."; } } else { LabelAddStatus.Text = "Unable to accept file type."; } } public IQueryable GetCategories() { var _db = new WingtipToys.Models.ProductContext(); IQueryable query = _db.Categories; return query; } public IQueryable GetProducts() { var _db = new WingtipToys.Models.ProductContext(); IQueryable query = _db.Products; return query; } protected void RemoveProductButton_Click(object sender, EventArgs e) { using (var _db = new WingtipToys.Models.ProductContext()) { int productId = Convert.ToInt16(DropDownRemoveProduct.SelectedValue); var myItem = (from c in _db.Products where c.ProductID == productId select c).FirstOrDefault(); if (myItem != null) { _db.Products.Remove(myItem); _db.SaveChanges(); // Reload the page. string pageUrl = Request.Url.AbsoluteUri.Substring(0, Request.Url.AbsoluteUri.Count() - Request.Url.Query.Count()); Response.Redirect(pageUrl + "?ProductAction=remove"); } else { LabelRemoveStatus.Text = "Unable to locate product."; } } } } }
Im Code, den Sie für die CodeBehind-Datei AdminPage.aspx.cs eingegeben haben, übernimmt eine Klasse namens AddProducts
die eigentliche Arbeit beim Hinzufügen von Produkten zur Datenbank. Diese Klasse ist noch nicht vorhanden, sodass Sie sie jetzt erstellen.
Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf den Ordner Logic, und wählen Sie dann Hinzufügen –>Neues Element aus.
Das Dialogfeld Neues Element hinzufügen wird angezeigt.Wählen Sie links die Gruppe Visual C# ->Code-Vorlagen aus. Wählen Sie dann klasseaus der mittleren Liste aus, und nennen Sie sie AddProducts.cs.
Die neue Klassendatei wird angezeigt.Ersetzen Sie den vorhandenen Code durch folgenden Code:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using WingtipToys.Models; namespace WingtipToys.Logic { public class AddProducts { public bool AddProduct(string ProductName, string ProductDesc, string ProductPrice, string ProductCategory, string ProductImagePath) { var myProduct = new Product(); myProduct.ProductName = ProductName; myProduct.Description = ProductDesc; myProduct.UnitPrice = Convert.ToDouble(ProductPrice); myProduct.ImagePath = ProductImagePath; myProduct.CategoryID = Convert.ToInt32(ProductCategory); using (ProductContext _db = new ProductContext()) { // Add product to DB. _db.Products.Add(myProduct); _db.SaveChanges(); } // Success. return true; } } }
Auf der Seite AdminPage.aspx kann der Benutzer, der der Rolle "canEdit" angehört, Produkte hinzufügen und entfernen. Wenn ein neues Produkt hinzugefügt wird, werden die Details zum Produkt überprüft und dann in die Datenbank eingegeben. Das neue Produkt steht allen Benutzern der Webanwendung sofort zur Verfügung.
Unauffällige Validierung
Die Produktdetails, die der Benutzer auf der Seite AdminPage.aspx bereitstellt, werden mithilfe von Validierungssteuerelementen (RequiredFieldValidator
und RegularExpressionValidator
) überprüft. Diese Steuerelemente verwenden automatisch eine unaufdringliche Validierung. Die unauffällige Validierung ermöglicht es den Validierungssteuerelementen, JavaScript für die clientseitige Validierungslogik zu verwenden. Dies bedeutet, dass für die Überprüfung der Seite kein Trip zum Server erforderlich ist. Standardmäßig ist die unaufdringliche Validierung basierend auf der folgenden Konfigurationseinstellung in der Web.config-Datei enthalten:
<add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms" />
Reguläre Ausdrücke
Der Produktpreis auf der Seite AdminPage.aspx wird mithilfe eines RegularExpressionValidator-Steuerelements überprüft. Dieses Steuerelement überprüft, ob der Wert des zugeordneten Eingabesteuerelements (textBox "AddProductPrice") mit dem vom regulären Ausdruck angegebenen Muster übereinstimmt. Ein regulärer Ausdruck ist eine Musterabgleichsnotation, mit der Sie bestimmte Zeichenmuster schnell finden und abgleichen können. Das RegularExpressionValidator-Steuerelement enthält eine Eigenschaft namens ValidationExpression
, die den regulären Ausdruck enthält, der zum Überprüfen der Preiseingabe verwendet wird, wie unten gezeigt:
<asp:RegularExpressionValidator
ID="RegularExpressionValidator1" runat="server"
Text="* Must be a valid price without $." ControlToValidate="AddProductPrice"
SetFocusOnError="True" Display="Dynamic"
ValidationExpression="^[0-9]*(\.)?[0-9]?[0-9]?$">
</asp:RegularExpressionValidator>
FileUpload-Steuerelement
Zusätzlich zu den Eingabe- und Validierungssteuerelementen haben Sie das FileUpload-Steuerelement zur Seite AdminPage.aspx hinzugefügt. Dieses Steuerelement bietet die Möglichkeit, Dateien hochzuladen. In diesem Fall erlauben Sie nur das Hochladen von Bilddateien. Wenn AddProductButton
in der CodeBehind-Datei (AdminPage.aspx.cs) geklickt wird, überprüft der Code die HasFile
-Eigenschaft des FileUpload-Steuerelements. Wenn das Steuerelement über eine Datei verfügt und der Dateityp (basierend auf der Dateierweiterung) zulässig ist, wird das Bild im Ordner Images und im Ordner Images/Thumbs der Anwendung gespeichert.
Modellbindung
Weiter oben in dieser Tutorialreihe haben Sie die Modellbindung verwendet, um ein ListView-Steuerelement , ein FormsView-Steuerelement , ein GridView-Steuerelement und ein DetailView-Steuerelement aufzufüllen. In diesem Tutorial verwenden Sie die Modellbindung, um ein DropDownList-Steuerelement mit einer Liste von Produktkategorien aufzufüllen.
Das Markup, das Sie der Datei AdminPage.aspx hinzugefügt haben, enthält ein DropDownList-Steuerelement namens DropDownAddCategory
:
<asp:DropDownList ID="DropDownAddCategory" runat="server"
ItemType="WingtipToys.Models.Category"
SelectMethod="GetCategories" DataTextField="CategoryName"
DataValueField="CategoryID" >
</asp:DropDownList>
Sie verwenden die Modellbindung, um diese DropDownList aufzufüllen, indem Sie das ItemType
Attribut und das SelectMethod
Attribut festlegen. Das ItemType
-Attribut gibt an, dass Sie den WingtipToys.Models.Category
Typ beim Auffüllen des Steuerelements verwenden. Sie haben diesen Typ zu Beginn dieser Tutorialreihe definiert, indem Sie die Category
-Klasse erstellen (siehe unten). Die Category
-Klasse befindet sich im Ordner Models in der Datei Category.cs .
public class Category
{
[ScaffoldColumn(false)]
public int CategoryID { get; set; }
[Required, StringLength(100), Display(Name = "Name")]
public string CategoryName { get; set; }
[Display(Name = "Product Description")]
public string Description { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
Das SelectMethod
Attribut des DropDownList-Steuerelements gibt an, dass Sie die GetCategories
-Methode (siehe unten) verwenden, die in der CodeBehind-Datei (AdminPage.aspx.cs) enthalten ist.
public IQueryable GetCategories()
{
var _db = new WingtipToys.Models.ProductContext();
IQueryable query = _db.Categories;
return query;
}
Diese Methode gibt an, dass eine IQueryable
Schnittstelle verwendet wird, um eine Abfrage anhand eines Typs Category
auszuwerten. Der zurückgegebene Wert wird verwendet, um die DropDownList im Markup der Seite (AdminPage.aspx) aufzufüllen.
Der für jedes Element in der Liste angezeigte Text wird durch Festlegen des DataTextField
Attributs angegeben. Das DataTextField
-Attribut verwendet die CategoryName
der Category
-Klasse (siehe oben), um jede Kategorie im DropDownList-Steuerelement anzuzeigen. Der tatsächliche Wert, der übergeben wird, wenn ein Element im DropDownList-Steuerelement ausgewählt wird, basiert auf dem DataValueField
-Attribut. Das DataValueField
Attribut wird auf festgelegt CategoryID
, wie in der Category
-Klasse definiert (siehe oben).
Funktionsweise der Anwendung
Wenn der Benutzer, der der Rolle "canEdit" angehört, zum ersten Mal zur Seite navigiert, wird das DropDownAddCategory
DropDownList-Steuerelement wie oben beschrieben aufgefüllt. Das DropDownRemoveProduct
DropDownList-Steuerelement wird auch mit Produkten aufgefüllt, die denselben Ansatz verwenden. Der Benutzer, der der Rolle "canEdit" angehört, wählt den Kategorietyp aus und fügt Produktdetails hinzu (Name, Beschreibung, Preis und Bilddatei). Wenn der Benutzer, der der Rolle "canEdit" angehört, auf die Schaltfläche Produkt hinzufügen klickt, wird der AddProductButton_Click
Ereignishandler ausgelöst. Der AddProductButton_Click
Ereignishandler in der CodeBehind-Datei (AdminPage.aspx.cs) überprüft die Bilddatei, um sicherzustellen, dass sie mit den zulässigen Dateitypen (.gif, .png, .jpeg oder .jpg) übereinstimmt. Anschließend wird die Bilddatei in einem Ordner der Wingtip Toys-Beispielanwendung gespeichert. Als Nächstes wird das neue Produkt der Datenbank hinzugefügt. Um das Hinzufügen eines neuen Produkts zu erreichen, wird eine neue instance der AddProducts
-Klasse erstellt und mit dem Namen Products bezeichnet. Die AddProducts
-Klasse verfügt über eine Methode namens AddProduct
, und das Products-Objekt ruft diese Methode auf, um der Datenbank Produkte hinzuzufügen.
// Add product data to DB.
AddProducts products = new AddProducts();
bool addSuccess = products.AddProduct(AddProductName.Text, AddProductDescription.Text,
AddProductPrice.Text, DropDownAddCategory.SelectedValue, ProductImage.FileName);
Wenn der Code das neue Produkt erfolgreich zur Datenbank hinzufügt, wird die Seite mit dem Wert ProductAction=add
der Abfragezeichenfolge erneut geladen.
Response.Redirect(pageUrl + "?ProductAction=add");
Wenn die Seite erneut geladen wird, wird die Abfragezeichenfolge in der URL enthalten. Durch erneutes Laden der Seite kann der Benutzer, der der Rolle "canEdit" angehört, sofort die Updates in den DropDownList-Steuerelementen auf der Seite AdminPage.aspx sehen. Außerdem kann die Seite, indem Sie die Abfragezeichenfolge mit der URL einschließen, eine Erfolgsmeldung für den Benutzer anzeigen, der zur Rolle "canEdit" gehört.
Wenn die Seite AdminPage.aspx erneut geladen wird, wird das Page_Load
-Ereignis aufgerufen.
protected void Page_Load(object sender, EventArgs e)
{
string productAction = Request.QueryString["ProductAction"];
if (productAction == "add")
{
LabelAddStatus.Text = "Product added!";
}
if (productAction == "remove")
{
LabelRemoveStatus.Text = "Product removed!";
}
}
Der Page_Load
Ereignishandler überprüft den Wert der Abfragezeichenfolge und bestimmt, ob eine Erfolgsmeldung angezeigt werden soll.
Ausführen der Anwendung
Sie können die Anwendung jetzt ausführen, um zu sehen, wie Sie Elemente im Warenkorb hinzufügen, löschen und aktualisieren können. Die Warenkorbsumme spiegelt die Gesamtkosten aller Artikel im Warenkorb wider.
Drücken Sie in Projektmappen-Explorer F5, um die Wingtip Toys-Beispielanwendung auszuführen.
Der Browser wird geöffnet und zeigt die Seite Default.aspx an.Klicken Sie oben auf der Seite auf den Link Anmelden .
Die Seite Login.aspx wird angezeigt.
Geben Sie den Benutzernamen und das Kennwort ein.
Klicken Sie unten auf der Seite auf die Schaltfläche Anmelden.
Wählen Sie oben auf der nächsten Seite den Link Admin aus, um zur Seite AdminPage.aspx zu navigieren.
Klicken Sie zum Testen der Eingabevalidierung auf die Schaltfläche Produkt hinzufügen , ohne Produktdetails hinzuzufügen.
Beachten Sie, dass die erforderlichen Feldmeldungen angezeigt werden.
Fügen Sie die Details für ein neues Produkt hinzu, und klicken Sie dann auf die Schaltfläche Produkt hinzufügen .
Wählen Sie im oberen Navigationsmenü Produkte aus, um das neue Produkt anzuzeigen, das Sie hinzugefügt haben.
Klicken Sie auf den Link Admin, um zur Verwaltungsseite zurückzukehren.
Wählen Sie auf der Seite im Abschnitt Produkt entfernen das neue Produkt aus, das Sie in DropDownListBox hinzugefügt haben.
Klicken Sie auf die Schaltfläche Produkt entfernen , um das neue Produkt aus der Anwendung zu entfernen.
Wählen Sie im oberen Navigationsmenü Produkte aus, um zu bestätigen, dass das Produkt entfernt wurde.
Klicken Sie auf Abmelden , um den Verwaltungsmodus zu verwenden.
Beachten Sie, dass im oberen Navigationsbereich das menüelement Admin nicht mehr angezeigt wird.
Zusammenfassung
In diesem Tutorial haben Sie eine benutzerdefinierte Rolle und einen Benutzer hinzugefügt, der der benutzerdefinierten Rolle angehört, den Zugriff auf den Verwaltungsordner und die Seite eingeschränkt und die Navigation für den Benutzer bereitgestellt, der zur benutzerdefinierten Rolle gehört. Sie haben die Modellbindung verwendet, um ein DropDownList-Steuerelement mit Daten aufzufüllen. Sie haben das FileUpload-Steuerelement und die Validierungssteuerelemente implementiert. Außerdem haben Sie gelernt, wie Sie Einer Datenbank Produkte hinzufügen und daraus entfernen. Im nächsten Tutorial erfahren Sie, wie Sie ASP.NET Routing implementieren.
Zusätzliche Ressourcen
Web.config – Authorization-Element
ASP.NET Identity
Bereitstellen einer Secure ASP.NET Web Forms-App mit Mitgliedschaft, OAuth und SQL-Datenbank auf einer Azure-Website
Microsoft Azure – Kostenlose Testversion