Appartenance et administration

par Erik Reitan

Cette série de tutoriels vous apprend les principes de base de la création d’une application Web Forms ASP.NET à l’aide de ASP.NET 4.5 et de Microsoft Visual Studio Express 2013 pour le web. Un projet Visual Studio 2013 avec du code source C# est disponible pour accompagner cette série de tutoriels.

Ce tutoriel vous montre comment mettre à jour l’exemple d’application Wingtip Toys pour ajouter un rôle personnalisé et utiliser ASP.NET Identity. Il vous montre également comment implémenter une page d’administration à partir de laquelle l’utilisateur disposant d’un rôle personnalisé peut ajouter et supprimer des produits du site web.

ASP.NET Identity est le système d’appartenance utilisé pour générer ASP.NET application web et est disponible dans ASP.NET 4.5. ASP.NET Identity est utilisé dans le modèle de projet Visual Studio 2013 Web Forms, ainsi que les modèles pour ASP.NET MVC, ASP.NET API web et ASP.NET application monopage. Vous pouvez également installer spécifiquement le système d’identité ASP.NET à l’aide de NuGet lorsque vous démarrez avec une application web vide. Toutefois, dans cette série de tutoriels, vous utilisez le projet Web Forms, qui inclut le système d’identité ASP.NET. ASP.NET Identity facilite l’intégration des données de profil spécifiques à l’utilisateur avec les données d’application. En outre, ASP.NET Identity vous permet de choisir le modèle de persistance pour les profils utilisateur dans votre application. Vous pouvez stocker les données dans une base de données SQL Server ou un autre magasin de données, y compris les magasins de données NoSQL tels que les tables de stockage Windows Azure.

Ce tutoriel s’appuie sur le didacticiel précédent intitulé « Paiement et paiement avec PayPal » dans la série de tutoriels Wingtip Toys.

Ce que vous allez apprendre :

  • Comment utiliser du code pour ajouter un rôle personnalisé et un utilisateur à l’application.
  • Comment restreindre l’accès au dossier d’administration et à la page.
  • Comment fournir une navigation pour l’utilisateur qui appartient au rôle personnalisé.
  • Comment utiliser la liaison de modèle pour remplir un contrôle DropDownList avec des catégories de produits.
  • Comment charger un fichier dans l’application web à l’aide du contrôle FileUpload .
  • Comment utiliser des contrôles de validation pour implémenter la validation d’entrée.
  • Comment ajouter et supprimer des produits de l’application.

Ces fonctionnalités sont incluses dans le tutoriel :

  • ASP.NET Identity
  • Configuration et autorisation
  • Liaison de modèle
  • Validation discrète

ASP.NET Web Forms fournit des fonctionnalités d’appartenance. À l’aide du modèle par défaut, vous disposez de fonctionnalités d’appartenance intégrées que vous pouvez utiliser immédiatement lors de l’exécution de l’application. Ce tutoriel vous montre comment utiliser ASP.NET Identity pour ajouter un rôle personnalisé et affecter un utilisateur à ce rôle. Vous allez apprendre à restreindre l’accès au dossier d’administration. Vous allez ajouter une page au dossier d’administration qui permet à un utilisateur disposant d’un rôle personnalisé d’ajouter et de supprimer des produits, et d’afficher un aperçu d’un produit une fois qu’il a été ajouté.

Ajout d’un rôle personnalisé

À l’aide de ASP.NET Identity, vous pouvez ajouter un rôle personnalisé et affecter un utilisateur à ce rôle à l’aide du code.

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le dossier Logique et créez une classe.

  2. Nommez la nouvelle classe RoleActions.cs.

  3. Modifiez le code pour qu’il apparaisse comme suit :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace WingtipToys.Logic
    {
        internal class RoleActions
        {
        }
    }
    
  4. Dans l’Explorateur de solutions, ouvrez le fichier Global.asax.cs .

  5. Modifiez le fichier Global.asax.cs en ajoutant le code en jaune afin qu’il apparaisse comme suit :

    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();
            }
        }
    }
    
  6. Notez que AddUserAndRole est souligné en rouge. Double-cliquez sur le code AddUserAndRole.
    La lettre « A » au début de la méthode mise en surbrillance sera soulignée.

  7. Pointez sur la lettre « A » et cliquez sur l’interface utilisateur qui vous permet de générer un stub de méthode pour la AddUserAndRole méthode.

    Appartenance et administration - Générer un stub de méthode

  8. Cliquez sur l’option intitulée :
    Generate method stub for "AddUserAndRole" in "WingtipToys.Logic.RoleActions"

  9. Ouvrez le fichier RoleActions.cs à partir du dossier Logique .
    La AddUserAndRole méthode a été ajoutée au fichier de classe.

  10. Modifiez le fichier RoleActions.cs en supprimant et NotImplementedException en ajoutant le code mis en surbrillance en jaune afin qu’il apparaisse comme suit :

    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");
          }
        }
      }
    }
    

Le code ci-dessus établit d’abord un contexte de base de données pour la base de données d’appartenance. La base de données d’appartenance est également stockée en tant que fichier .mdf dans le dossier App_Data . Vous serez en mesure d’afficher cette base de données une fois que le premier utilisateur s’est connecté à cette application web.

Note

Si vous souhaitez stocker les données d’appartenance avec les données de produit, vous pouvez envisager d’utiliser le même DbContext que celui que vous avez utilisé pour stocker les données de produit dans le code ci-dessus.

Le mot clé interne est un modificateur d’accès pour les types (tels que les classes) et les membres de type (comme les méthodes ou les propriétés). Les types internes ou les membres sont accessibles uniquement dans les fichiers contenus dans le même assembly (fichier.dll ). Lorsque vous générez votre application, un fichier d’assembly (.dll) est créé qui contient le code exécuté lors de l’exécution de votre application.

Un objet, qui fournit la RoleStore gestion des rôles, est créé en fonction du contexte de base de données.

Note

Notez que lorsque l’objet RoleStore est créé, il utilise un type générique IdentityRole . Cela signifie que le RoleStore est uniquement autorisé à contenir des objets IdentityRole. En outre, en utilisant des génériques, les ressources en mémoire sont gérées mieux.

Ensuite, l’objet RoleManager est créé en fonction de l’objet RoleStore que vous venez de créer. l’objet expose l’API RoleManager associée au rôle qui peut être utilisée pour enregistrer automatiquement les modifications dans le RoleStore. Le RoleManager ne peut contenir que des objets IdentityRole, car le code utilise le type générique <IdentityRole>.

Vous appelez la RoleExists méthode pour déterminer si le rôle « canEdit » est présent dans la base de données d’appartenance. Si ce n’est pas le cas, vous créez le rôle.

La création de l’objet UserManager semble être plus compliquée que le RoleManager contrôle, mais il est presque identique. Il est juste codé sur une ligne plutôt que plusieurs. Ici, le paramètre que vous passez est instancié en tant qu'un nouvel objet à l'intérieur des parenthèses.

Ensuite, vous créez l’utilisateur « canEditUser » en créant un ApplicationUser objet. Ensuite, si vous parvenez à créer l'utilisateur, vous l'ajoutez au nouveau rôle.

Note

La gestion des erreurs sera mise à jour pendant le didacticiel « gestion des erreurs ASP.NET » plus loin dans cette série de tutoriels.

La prochaine fois que l’application démarre, l’utilisateur nommé « canEditUser » sera ajouté en tant que rôle nommé « canEdit » de l’application. Plus loin dans ce tutoriel, vous allez vous connecter en tant qu’utilisateur « canEditUser » pour afficher des fonctionnalités supplémentaires que vous allez ajouter pendant ce didacticiel. Pour plus d’informations sur ASP.NET Identity, consultez l’espace de noms Microsoft.AspNet.Identity. Pour plus d’informations sur l’initialisation du système ASP.NET Identity, consultez aspnetIdentitySample.

Restriction de l’accès à la page Administration

L’exemple d’application Wingtip Toys permet aux utilisateurs anonymes et aux utilisateurs connectés d’afficher et d’acheter des produits. Toutefois, l’utilisateur connecté disposant du rôle personnalisé « canEdit » peut accéder à une page restreinte afin d’ajouter et de supprimer des produits.

Ajouter un dossier d’administration et une page

Ensuite, vous allez créer un dossier nommé Admin pour l’utilisateur « canEditUser » appartenant au rôle personnalisé de l’exemple d’application Wingtip Toys.

  1. Cliquez avec le bouton droit sur le nom du projet (Wingtip Toys) dans l’Explorateur de solutions , puis sélectionnez Ajouter ->Nouveau dossier.
  2. Nommez le nouveau dossier Admin.
  3. Cliquez avec le bouton droit sur le dossier Administrateur , puis sélectionnez Ajouter ->Nouvel élément.
    La boîte de dialogue Ajouter un nouvel élément s’affiche.
  4. Sélectionnez le groupe de modèles Visual C#->Web à gauche. Dans la liste centrale, sélectionnez Formulaire web avec page maître, nommez-le AdminPage.aspx, puis sélectionnez Ajouter.
  5. Sélectionnez le fichier Site.Master comme page maître, puis choisissez OK.

Ajouter un fichier Web.config

En ajoutant un fichier Web.config au dossier Administrateur , vous pouvez restreindre l’accès à la page contenue dans le dossier.

  1. Cliquez avec le bouton droit sur le dossier Administrateur , puis sélectionnez Ajouter ->Nouvel élément.
    La boîte de dialogue Ajouter un nouvel élément s’affiche.

  2. Dans la liste des modèles web Visual C#, sélectionnez Fichier de configuration webdans la liste centrale, acceptez le nom par défaut de Web.config, puis sélectionnez Ajouter.

  3. Remplacez le contenu XML existant dans le fichier Web.config par les éléments suivants :

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <authorization>
          <allow roles="canEdit"/>
          <deny users="*"/>
        </authorization>
      </system.web>
    </configuration>
    

Enregistrez le fichier Web.config . Le fichier Web.config spécifie que seul l’utilisateur appartenant au rôle « canEdit » de l’application peut accéder à la page contenue dans le dossier Administrateur .

Inclusion de la navigation de rôle personnalisé

Pour permettre à l’utilisateur du rôle personnalisé « canEdit » d’accéder à la section d’administration de l’application, vous devez ajouter un lien à la page Site.Master . Seuls les utilisateurs qui appartiennent au rôle « canEdit » pourront voir le lien Administrateur et accéder à la section d’administration.

  1. Dans l’Explorateur de solutions, recherchez et ouvrez la page Site.Master .

  2. Pour créer un lien pour l’utilisateur du rôle « canEdit », ajoutez le balisage mis en surbrillance en jaune à l’élément de liste <ul> non ordonné suivant afin que la liste apparaisse comme suit :

    <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">&nbsp;</a></li>
    </ul>
    
  3. Ouvrez le fichier Site.Master.cs . Rendez le lien Admin visible uniquement pour l'utilisateur « canEditUser » en ajoutant le code mis en surbrillance en jaune au Page_Load gestionnaire. Le Page_Load gestionnaire s’affiche comme suit :

    protected void Page_Load(object sender, EventArgs e)
    {
        if (HttpContext.Current.User.IsInRole("canEdit"))
        {
            adminLink.Visible = true;
        }
    }
    

Lorsque la page se charge, le code vérifie si l’utilisateur connecté a le rôle « canEdit ». Si l’utilisateur appartient au rôle « canEdit », l’élément d’étendue contenant le lien vers la page AdminPage.aspx (et par conséquent le lien à l’intérieur de l’étendue) est rendu visible.

Autorisation de l’administration du produit

Jusqu’à présent, vous avez créé le rôle « canEdit » et ajouté un utilisateur « canEditUser », un dossier d’administration et une page d’administration. Vous avez défini les droits d’accès pour le dossier d’administration et la page, et vous avez ajouté un lien de navigation pour l’utilisateur du rôle « canEdit » à l’application. Ensuite, vous allez ajouter du balisage à la page AdminPage.aspx et du code au fichier AdminPage.aspx.cs code-behind qui permettra à l’utilisateur avec le rôle "canEdit" d’ajouter et de supprimer des produits.

  1. Dans l’Explorateur de solutions, ouvrez le fichier AdminPage.aspx à partir du dossier Administrateur .

  2. Remplacez le balisage existant par les éléments suivants :

    <%@ 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>
    
  3. Ensuite, ouvrez le fichier code-behind AdminPage.aspx.cs en cliquant avec le bouton droit sur le AdminPage.aspx et en cliquant sur Afficher le code.

  4. Remplacez le code existant dans le fichier code-behind AdminPage.aspx.cs par le code suivant :

    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.";
            }
          }
        }
      }
    }
    

Dans le code que vous avez entré pour le fichier code-behind AdminPage.aspx.cs , une classe appelée AddProducts effectue le travail réel d’ajout de produits à la base de données. Cette classe n’existe pas encore. Vous allez donc la créer maintenant.

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le dossier Logique , puis sélectionnez Ajouter ->Nouvel élément.
    La boîte de dialogue Ajouter un nouvel élément s’affiche.

  2. Sélectionnez le groupe de modèles Visual C# ->Code à gauche. Ensuite, sélectionnez Classedans la liste intermédiaire et nommez-la AddProducts.cs.
    Le nouveau fichier de classe s’affiche.

  3. Remplacez le code existant par le code ci-dessous :

    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;
            }
        }
    }
    

La page AdminPage.aspx permet à l’utilisateur appartenant au rôle « canEdit » d’ajouter et de supprimer des produits. Lorsqu’un nouveau produit est ajouté, les détails sur le produit sont validés, puis entrés dans la base de données. Le nouveau produit est immédiatement disponible pour tous les utilisateurs de l’application web.

Validation discrète

Les détails du produit que l’utilisateur fournit sur la page AdminPage.aspx sont validés à l’aide de contrôles de validation (RequiredFieldValidator et RegularExpressionValidator). Ces contrôles utilisent automatiquement une validation discrète. La validation non discrète permet aux contrôles de validation d’utiliser JavaScript pour la logique de validation côté client, ce qui signifie que la page ne nécessite pas de passage au serveur pour être validée. Par défaut, la validation non discrète est incluse dans le fichier Web.config en fonction du paramètre de configuration suivant :

<add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms" />

Expressions régulières

Le prix du produit sur la page AdminPage.aspx est validé à l’aide d’un contrôle RegularExpressionValidator . Ce contrôle valide si la valeur du contrôle d’entrée associé (la zone de texte « AddProductPrice ») correspond au modèle spécifié par l’expression régulière. Une expression régulière est une notation de correspondance de modèle qui vous permet de rechercher et de faire correspondre rapidement des modèles de caractères spécifiques. Le contrôle RegularExpressionValidator inclut une propriété nommée ValidationExpression qui contient l’expression régulière utilisée pour valider l’entrée de prix, comme indiqué ci-dessous :

<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>

Contrôle de téléversement de fichier

Outre les contrôles d’entrée et de validation, vous avez ajouté le contrôle FileUpload à la page AdminPage.aspx . Ce contrôle offre la possibilité de charger des fichiers. Dans ce cas, vous autorisez uniquement le chargement des fichiers image. Dans le fichier code-behind (AdminPage.aspx.cs), lorsque AddProductButton est cliqué, le code vérifie la HasFile propriété du contrôle FileUpload. Si le contrôle a un fichier et si le type de fichier (basé sur l’extension de fichier) est autorisé, l’image est enregistrée dans le dossier Images et dans le dossier Images/Thumbs de l’application.

Liaison de modèle

Plus haut dans cette série de tutoriels, vous avez utilisé la liaison de modèle pour remplir un contrôle ListView , un contrôle FormsView , un contrôle GridView et un contrôle DetailView . Dans ce tutoriel, vous utilisez la liaison de modèle pour remplir un contrôle DropDownList avec une liste de catégories de produits.

Le balisage que vous avez ajouté au fichier AdminPage.aspx contient un contrôle DropDownList appelé DropDownAddCategory:

<asp:DropDownList ID="DropDownAddCategory" runat="server" 
        ItemType="WingtipToys.Models.Category" 
        SelectMethod="GetCategories" DataTextField="CategoryName" 
        DataValueField="CategoryID" >
    </asp:DropDownList>

Vous utilisez la liaison de modèle pour remplir ce DropDownList en définissant l’attribut ItemType et l’attribut SelectMethod . L’attribut ItemType spécifie que vous utilisez le WingtipToys.Models.Category type lors du remplissage du contrôle. Vous avez défini ce type au début de cette série de tutoriels en créant la Category classe (illustrée ci-dessous). La Category classe se trouve dans le dossier Models à l’intérieur du fichier 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; }
}

L’attribut SelectMethod du contrôle DropDownList spécifie que vous utilisez la GetCategories méthode (illustrée ci-dessous) incluse dans le fichier code-behind (AdminPage.aspx.cs).

public IQueryable GetCategories()
{
  var _db = new WingtipToys.Models.ProductContext();
  IQueryable query = _db.Categories;
  return query;
}

Cette méthode spécifie qu’une IQueryable interface est utilisée pour évaluer une requête par rapport à un Category type. La valeur retournée est utilisée pour remplir la liste déroulante dans le balisage de la page (AdminPage.aspx).

Le texte affiché pour chaque élément de la liste est spécifié en définissant l’attribut DataTextField . L’attribut DataTextField utilise la CategoryNameCategory classe (illustrée ci-dessus) pour afficher chaque catégorie dans le contrôle DropDownList . La valeur réelle qui est transmise lors de la sélection d'un élément dans le contrôle DropDownList est déterminée par l’attribut DataValueField. L’attribut DataValueField est défini pour CategoryID dans la classe Category (illustré ci-dessus).

Fonctionnement de l’application

Lorsque l’utilisateur appartenant au rôle « canEdit » accède à la page pour la première fois, le DropDownAddCategory contrôle DropDownList est rempli comme décrit ci-dessus. Le DropDownRemoveProduct contrôle DropDownList est également rempli avec des produits à l’aide de la même approche. L’utilisateur appartenant au rôle « canEdit » sélectionne le type de catégorie et ajoute les détails du produit (Nom, Description, Prix et Fichier image). Lorsque l’utilisateur appartenant au rôle « canEdit » clique sur le bouton Ajouter un produit , le AddProductButton_Click gestionnaire d’événements est déclenché. Le AddProductButton_Click gestionnaire d’événements situé dans le fichier code-behind (AdminPage.aspx.cs) vérifie que le fichier image correspond aux types de fichiers autorisés (.gif, .png, .jpeg ou .jpg). Ensuite, le fichier image est enregistré dans un dossier de l’exemple d’application Wingtip Toys. Ensuite, le nouveau produit est ajouté à la base de données. Pour ajouter un nouveau produit, une nouvelle instance de la classe AddProducts est créée et nommée produits. La AddProducts classe a une méthode nommée AddProduct, et l’objet products appelle cette méthode pour ajouter des produits à la base de données.

// Add product data to DB.
AddProducts products = new AddProducts();
bool addSuccess = products.AddProduct(AddProductName.Text, AddProductDescription.Text,
    AddProductPrice.Text, DropDownAddCategory.SelectedValue, ProductImage.FileName);

Si le code ajoute correctement le nouveau produit à la base de données, la page est rechargée avec la valeur ProductAction=addde chaîne de requête .

Response.Redirect(pageUrl + "?ProductAction=add");

Lorsque la page recharge, la chaîne de requête est incluse dans l’URL. En rechargeant la page, l’utilisateur appartenant au rôle « canEdit » peut immédiatement voir les mises à jour dans les contrôles DropDownList sur la page AdminPage.aspx . En outre, en incluant la chaîne de requête avec l’URL, la page peut afficher un message de réussite à l’utilisateur appartenant au rôle « canEdit ».

Lorsque la page AdminPage.aspx recharge, l’événement Page_Load est appelé.

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!";
    }
}

Le Page_Load gestionnaire d’événements vérifie la valeur de la chaîne de requête et détermine s’il faut afficher un message de réussite.

Exécution de l’application

Vous pouvez exécuter l’application maintenant pour voir comment ajouter, supprimer et mettre à jour des éléments dans le panier d’achat. Le total du panier d’achat reflète le coût total de tous les articles dans le panier d’achat.

  1. Dans l’Explorateur de solutions, appuyez sur F5 pour exécuter l’exemple d’application Wingtip Toys.
    Le navigateur s’ouvre et affiche la page Default.aspx .

  2. Cliquez sur le lien Se connecter en haut de la page.

    Appartenance et administration - Lien de connexion

    La page Login.aspx s’affiche.

  3. Entrez le nom d’utilisateur et le mot de passe.

    Appartenance et administration - Page Connexion

  4. Cliquez sur le bouton Se connecter en bas de la page.

  5. En haut de la page suivante, sélectionnez le lien Administrateur pour accéder à la page AdminPage.aspx .

    Appartenance et administration - Lien Administrateur

  6. Pour tester la validation d’entrée, cliquez sur le bouton Ajouter un produit sans ajouter de détails sur le produit.

    Appartenance et administration - Page d’administration

    Notez que les messages de champ requis sont affichés.

  7. Ajoutez les détails d’un nouveau produit, puis cliquez sur le bouton Ajouter un produit .

    Appartenance et administration - Ajouter un produit

  8. Sélectionnez Produits dans le menu de navigation supérieur pour afficher le nouveau produit que vous avez ajouté.

    Appartenance et administration - Afficher le nouveau produit

  9. Cliquez sur le lien Administrateur pour revenir à la page d’administration.

  10. Dans la section Supprimer le produit de la page, sélectionnez le nouveau produit que vous avez ajouté dans dropDownListBox.

  11. Cliquez sur le bouton Supprimer le produit pour supprimer le nouveau produit de l’application.

    Appartenance et administration - Supprimer le produit

  12. Sélectionnez Produits dans le menu de navigation supérieur pour confirmer que le produit a été supprimé.

  13. Cliquez sur Se déconnecter pour exister en mode d’administration.
    Notez que le volet de navigation supérieur n’affiche plus l’élément de menu Administrateur .

Résumé

Dans ce didacticiel, vous avez ajouté un rôle personnalisé et un utilisateur appartenant au rôle personnalisé, restreint l’accès au dossier d’administration et à la page, et fourni la navigation pour l’utilisateur appartenant au rôle personnalisé. Vous avez utilisé le liaisonnement du modèle pour remplir un contrôle DropDownList avec des données. Vous avez implémenté le contrôle FileUpload et les contrôles de validation. En outre, vous avez appris à ajouter et supprimer des produits d’une base de données. Dans le tutoriel suivant, vous allez apprendre à implémenter ASP.NET routage.

Ressources additionnelles

Web.config - élément d’autorisation
ASP.NET Identity
Déployer une application Web Forms sécurisée ASP.NET avec appartenance, OAuth et SQL Database sur un site web Azure
Microsoft Azure - Version d’évaluation gratuite