Partager via


Examen des événements associés à l’insertion, à la mise à jour et à la suppression (C#)

par Scott Mitchell

Télécharger le PDF

Dans ce tutoriel, nous allons examiner l’utilisation des événements qui se produisent avant, pendant et après une opération d’insertion, de mise à jour ou de suppression d’un contrôle web de données ASP.NET. Nous allons également voir comment personnaliser l’interface d’édition pour mettre à jour uniquement un sous-ensemble des champs de produit.

Introduction

Lorsque vous utilisez les fonctionnalités intégrées d’insertion, de modification ou de suppression des contrôles GridView, DetailsView ou FormView, diverses étapes se passent lorsque l’utilisateur final termine le processus d’ajout d’un nouvel enregistrement ou de la mise à jour ou de la suppression d’un enregistrement existant. Comme nous l’avons vu dans le tutoriel précédent, lorsqu’une ligne est modifiée dans GridView, le bouton Modifier est remplacé par les boutons Mettre à jour et Annuler et les Champs liés se transforment en Zones de texte. Une fois que l’utilisateur final met à jour les données et clique sur Mettre à jour, les étapes suivantes sont effectuées lors de la publication :

  1. GridView remplit ses ObjectDataSource UpdateParameters avec le ou les champs d’identification uniques de l’enregistrement modifié (via la DataKeyNames propriété) ainsi que les valeurs entrées par l’utilisateur
  2. GridView appelle sa méthode ObjectDataSource, qui appelle à son tour la méthode appropriée dans l’objet Update() sous-jacent (ProductsDAL.UpdateProductdans notre didacticiel précédent)
  3. Les données sous-jacentes, qui incluent désormais les modifications mises à jour, sont remonté à GridView

Pendant cette séquence d’étapes, un certain nombre d’événements se déclenchent, ce qui nous permet de créer des gestionnaires d’événements pour ajouter une logique personnalisée si nécessaire. Par exemple, avant l’étape 1, l’événement RowUpdating gridView se déclenche. Nous pouvons, à ce stade, annuler la demande de mise à jour en cas d’erreur de validation. Lorsque la Update() méthode est appelée, l’événement ObjectDataSource se déclenche, ce qui permet d’ajouter Updating ou de personnaliser les valeurs de l’un UpdateParametersdes objets . Une fois la méthode de l’objet sous-jacent de ObjectDataSource exécutée, l’événement Updated ObjectDataSource est déclenché. Un gestionnaire d’événements pour l’événement Updated peut inspecter les détails de l’opération de mise à jour, tels que le nombre de lignes affectées et si une exception s’est produite ou non. Enfin, après l’étape 2, l’événement de GridView se déclenche ; un gestionnaire d’événements pour cet événement peut examiner des informations supplémentaires sur l’opération RowUpdated de mise à jour juste effectuée.

La figure 1 illustre cette série d’événements et d’étapes lors de la mise à jour d’un GridView. Le modèle d’événement de la figure 1 n’est pas unique pour la mise à jour avec un GridView. L’insertion, la mise à jour ou la suppression de données à partir de GridView, DetailsView ou FormView précipite la même séquence d’événements de pré-niveau et de post-niveau pour le contrôle Web de données et l’ObjetDataSource.

Une série de pré-événements et post-événements se déclenchent lors de la mise à jour des données dans un GridView

Figure 1 : Une série de pré-événements et de post-événements se déclenche lors de la mise à jour des données dans un GridView (cliquez pour afficher l’image de taille complète)

Dans ce tutoriel, nous allons examiner l’utilisation de ces événements pour étendre les fonctionnalités intégrées d’insertion, de mise à jour et de suppression des contrôles web de données ASP.NET. Nous allons également voir comment personnaliser l’interface d’édition pour mettre à jour uniquement un sous-ensemble des champs de produit.

Étape 1 : Mise à jour des champs etUnitPricedesProductNameproduits

Dans les interfaces de modification du didacticiel précédent, tous les champs de produit qui n’étaient pas en lecture seule doivent être inclus. Si nous étions à supprimer un champ de GridView , par exemple QuantityPerUnit , lors de la mise à jour des données, le contrôle Web de données ne définirait pas la valeur de QuantityPerUnit UpdateParameters ObjectDataSource. ObjectDataSource passerait ensuite une null valeur à la UpdateProduct méthode BLL (Business Logic Layer), ce qui modifierait la colonne de l’enregistrement de base de QuantityPerUnit données modifié en valeur NULL . De même, si un champ obligatoire, tel que ProductName, est supprimé de l’interface d’édition, la mise à jour échoue avec une exception « Column 'ProductName' ne permet pas les valeurs Null ». La raison de ce comportement était que ObjectDataSource a été configuré pour appeler la méthode de UpdateProduct la ProductsBLL classe, ce qui attendait un paramètre d’entrée pour chacun des champs de produit. Par conséquent, la collection ObjectDataSource UpdateParameters contenait un paramètre pour chacun des paramètres d’entrée de la méthode.

Si nous voulons fournir un contrôle Web de données qui permet à l’utilisateur final de mettre à jour uniquement un sous-ensemble de champs, nous devons définir par programme les valeurs manquantes UpdateParameters dans le gestionnaire d’événements Updating ObjectDataSource ou créer et appeler une méthode BLL qui attend uniquement un sous-ensemble des champs. Examinons cette dernière approche.

Plus précisément, nous allons créer une page qui affiche uniquement les champs et UnitPrice les ProductName champs d’un GridView modifiable. L’interface d’édition de GridView permet uniquement à l’utilisateur de mettre à jour les deux champs affichés et ProductName UnitPrice. Étant donné que cette interface d’édition fournit uniquement un sous-ensemble des champs d’un produit, nous devons créer un ObjectDataSource qui utilise la méthode de BLL existante et dont les valeurs de UpdateProduct champ de produit manquantes sont définies par programme dans son Updating gestionnaire d’événements, ou nous devons créer une nouvelle méthode BLL qui attend uniquement le sous-ensemble de champs définis dans GridView. Pour ce tutoriel, utilisons cette dernière option et créons une surcharge de la UpdateProduct méthode, une qui prend seulement trois paramètres d’entrée : productName, unitPriceet productID:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Update, false)]
public bool UpdateProduct(string productName, decimal? unitPrice, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;

    Northwind.ProductsRow product = products[0];

    product.ProductName = productName;
    if (unitPrice == null) product.SetUnitPriceNull();
      else product.UnitPrice = unitPrice.Value;

    // Update the product record
    int rowsAffected = Adapter.Update(product);

    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

Comme la méthode d’origine UpdateProduct , cette surcharge commence par vérifier s’il existe un produit dans la base de données avec le fichier spécifié ProductID. Si ce n’est pas le cas, elle retourne false, indiquant que la demande de mise à jour des informations sur le produit a échoué. Sinon, il met à jour les champs et UnitPrice les enregistrements de ProductName produit existants en conséquence et valide la mise à jour en appelant la méthode de Update() TableAdapter, en passant l’instanceProductsRow.

Avec cet ajout à notre ProductsBLL classe, nous sommes prêts à créer l’interface GridView simplifiée. Ouvrez le DataModificationEvents.aspx EditInsertDelete dossier et ajoutez un GridView à la page. Créez un ObjectDataSource et configurez-le pour utiliser la ProductsBLL classe avec son Select() mappage de méthode et GetProducts son Update() mappage de méthode à la UpdateProduct surcharge qui prend uniquement les paramètres d’entrée unitPriceet productID les productNameparamètres d’entrée. La figure 2 montre l’Assistant Création d’une source de données lors du mappage de Update() la méthode ObjectDataSource à la nouvelle UpdateProduct surcharge de méthode de la ProductsBLL classe.

Mapper la méthode Update() de ObjectDataSource à la nouvelle surcharge UpdateProduct

Figure 2 : Mapper la méthode ObjectDataSource à la nouvelle UpdateProduct surcharge (cliquez pour afficher l’image Update()de taille complète)

Dans la mesure où notre exemple nécessite simplement la possibilité de modifier des données, mais pas d’insérer ou de supprimer des enregistrements, prenez un moment pour indiquer explicitement que les méthodes et Delete() les méthodes ObjectDataSource Insert() ne doivent pas être mappées à aucune des méthodes de la ProductsBLL classe en accédant aux onglets INSERT et DELETE et en choisissant (None) dans la liste déroulante.

Choisissez (Aucun) dans la liste déroulante pour les onglets INSERT et DELETE

Figure 3 : Choisir (Aucun) dans la liste déroulante des onglets INSERT et DELETE (cliquez pour afficher l’image de taille complète)

Une fois cet Assistant terminé, cochez la case Activer la modification à partir de la balise active de GridView.

Une fois l’Assistant Création d’une source de données terminée et la liaison à GridView, Visual Studio a créé la syntaxe déclarative pour les deux contrôles. Accédez à la vue Source pour inspecter le balisage déclaratif de ObjectDataSource, illustré ci-dessous :

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Étant donné qu’il n’existe aucun mappage pour les méthodes et Delete() les Insert() méthodes ObjectDataSource, il n’y a pas InsertParameters ou DeleteParameters de sections. En outre, étant donné que la Update() méthode est mappée à la UpdateProduct surcharge de méthode qui accepte uniquement trois paramètres d’entrée, la UpdateParameters section ne comporte que trois Parameter instances.

Notez que la propriété ObjectDataSource OldValuesParameterFormatString est définie sur original_{0}. Cette propriété est définie automatiquement par Visual Studio lors de l’utilisation de l’Assistant Configurer la source de données. Toutefois, étant donné que nos méthodes BLL ne s’attendent pas à ce que la valeur d’origine ProductID soit transmise, supprimez complètement cette affectation de propriété de la syntaxe déclarative de ObjectDataSource.

Remarque

Si vous effacez simplement la valeur de propriété OldValuesParameterFormatString de l’Fenêtre Propriétés dans la vue Création, la propriété existe toujours dans la syntaxe déclarative, mais elle est définie sur une chaîne vide. Supprimez complètement la propriété de la syntaxe déclarative ou, du Fenêtre Propriétés, définissez la valeur sur la valeur par défaut{0}.

Bien que ObjectDataSource ait UpdateParameters uniquement pour le nom, le prix et l’ID du produit, Visual Studio a ajouté un Objet BoundField ou CheckBoxField dans GridView pour chacun des champs du produit.

GridView contient un objet BoundField ou CheckBoxField pour chacun des champs du produit

Figure 4 : GridView contient un objet BoundField ou CheckBoxField pour chacun des champs du produit (cliquez pour afficher l’image de taille complète)

Lorsque l’utilisateur final modifie un produit et clique sur son bouton Mettre à jour, GridView énumère les champs qui n’étaient pas en lecture seule. Il définit ensuite la valeur du paramètre correspondant dans la collection ObjectDataSource UpdateParameters sur la valeur entrée par l’utilisateur. S’il n’existe pas de paramètre correspondant, GridView en ajoute un à la collection. Par conséquent, si notre GridView contient BoundFields et CheckBoxFields pour tous les champs du produit, ObjectDataSource appellera la UpdateProduct surcharge qui accepte tous ces paramètres, malgré le fait que le balisage déclaratif d’ObjectDataSource spécifie seulement trois paramètres d’entrée (voir figure 5). De même, s’il existe une combinaison de champs de produit non en lecture seule dans GridView qui ne correspondent pas aux paramètres d’entrée d’une UpdateProduct surcharge, une exception est levée lors de la tentative de mise à jour.

GridView ajoute des paramètres à la collection UpdateParameters de ObjectDataSource

Figure 5 : GridView ajoute des paramètres à la collection ObjectDataSource (cliquez pour afficher l’image UpdateParametersde taille complète)

Pour vous assurer que ObjectDataSource appelle la surcharge qui prend uniquement le UpdateProduct nom, le prix et l’ID du produit, nous devons limiter gridView à avoir des champs modifiables uniquement pour le ProductName produit et UnitPrice. Pour ce faire, supprimez les autres BoundFields et CheckBoxFields, en définissant la propriété truede ReadOnly ces autres champs sur , ou par une combinaison des deux. Pour ce tutoriel, nous allons simplement supprimer tous les champs GridView à l’exception des ProductName champs UnitPrice BoundFields, après quoi le balisage déclaratif de GridView se présente comme suit :

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>

Même si la UpdateProduct surcharge attend trois paramètres d’entrée, nous n’avons que deux BoundFields dans notre GridView. Cela est dû au fait que le productID paramètre d’entrée est une valeur de clé primaire et passé par la valeur de la DataKeyNames propriété pour la ligne modifiée.

Notre GridView, ainsi que la UpdateProduct surcharge, permet à un utilisateur de modifier uniquement le nom et le prix d’un produit sans perdre l’un des autres champs de produit.

L’interface permet de modifier uniquement le nom et le prix du produit

Figure 6 : L’interface permet de modifier uniquement le nom et le prix du produit (cliquez pour afficher l’image de taille complète)

Remarque

Comme indiqué dans le tutoriel précédent, il est essentiel que l’état d’affichage de GridView soit activé (comportement par défaut). Si vous définissez la propriété falseGridView EnableViewState sur , vous risquez d’avoir des utilisateurs simultanés à supprimer ou modifier involontairement des enregistrements.

Amélioration de laUnitPricemise en forme

Bien que l’exemple GridView présenté dans la figure 6 fonctionne, le UnitPrice champ n’est pas mis en forme du tout, ce qui entraîne un affichage de prix qui n’a pas de symboles monétaires et a quatre décimales. Pour appliquer une mise en forme monétaire pour les lignes non modifiables, définissez simplement la UnitPrice propriété boundField DataFormatString sur {0:c} et sa HtmlEncode propriété falsesur .

Définir les propriétés DataFormatString et HtmlEncode de UnitPrice en conséquence

Figure 7 : Définir les propriétés et HtmlEncode les DataFormatString propriétés en conséquence (cliquez pour afficher l’image UnitPricede taille complète)

Avec cette modification, les lignes non modifiables mettez en forme le prix en tant que devise ; toutefois, la ligne modifiée affiche toujours la valeur sans symbole monétaire et avec quatre décimales.

Les lignes non modifiables sont désormais mises en forme en tant que valeurs monétaires

Figure 8 : Les lignes non modifiables sont désormais mises en forme en tant que valeurs monétaires (cliquez pour afficher l’image de taille complète)

Les instructions de mise en forme spécifiées dans la DataFormatString propriété peuvent être appliquées à l’interface d’édition en définissant la propriété true boundField ApplyFormatInEditMode sur (la valeur par défaut est false). Prenez un moment pour définir cette propriété sur true.

Définir la propriété ApplyFormatInEditMode de UnitPrice BoundField sur true

Figure 9 : Définir la UnitPrice propriété true de ApplyFormatInEditMode BoundField sur (Cliquez pour afficher l’image de taille complète)

Avec cette modification, la valeur de l’affichage UnitPrice dans la ligne modifiée est également mise en forme en tant que devise.

Capture d’écran de GridView montrant la valeur UnitPrice de la ligne modifiée mise en forme en tant que devise.

Figure 10 : La valeur de la UnitPrice ligne modifiée est désormais mise en forme sous forme de devise (cliquez pour afficher l’image de taille complète)

Toutefois, la mise à jour d’un produit avec le symbole monétaire dans la zone de texte telle que $19.00 lève un FormatException. Lorsque GridView tente d’affecter les valeurs fournies par l’utilisateur à la collection ObjectDataSource UpdateParameters , il ne peut pas convertir la UnitPrice chaîne « $19.00 » en la decimal valeur requise par le paramètre (voir la figure 11). Pour résoudre ce problème, nous pouvons créer un gestionnaire d’événements pour l’événement gridView et l’analyser RowUpdating en UnitPrice tant que format monétaire decimal.

L’événement RowUpdating de GridView accepte comme deuxième paramètre un objet de type GridViewUpdateEventArgs, qui inclut un NewValues dictionnaire comme l’une de ses propriétés qui contient les valeurs fournies par l’utilisateur UpdateParameters prêtes à être affectées à la collection ObjectDataSource. Nous pouvons remplacer la valeur existante UnitPrice dans la NewValues collection avec une valeur décimale analysée à l’aide du format monétaire avec les lignes de code suivantes dans le RowUpdating gestionnaire d’événements :

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
  if (e.NewValues["UnitPrice"] != null)
    e.NewValues["UnitPrice"] =
        decimal.Parse(e.NewValues["UnitPrice"].ToString(),
            System.Globalization.NumberStyles.Currency);
}

Si l’utilisateur a fourni une UnitPrice valeur (par exemple, « $19.00 »), cette valeur est remplacée par la valeur décimale calculée par Decimal.Parse, en analysant la valeur en tant que devise. Cela analyse correctement la décimale en cas de symboles monétaires, virgules, décimales, et utilise l’énumération NumberStyles dans l’espace de noms System.Globalization.

La figure 11 montre à la fois le problème provoqué par les symboles monétaires dans le gestionnaire d’événements fourni UnitPricepar l’utilisateur, ainsi que la façon dont le gestionnaire d’événements RowUpdating de GridView peut être utilisé pour analyser correctement ces entrées.

Diagramme montrant comment ObjectDataSource traite le champ UnitPrice et comment le gestionnaire d’événements RowUpdate du GridView convertit une chaîne en décimale.

Figure 11 : La valeur de la UnitPrice ligne modifiée est désormais mise en forme sous forme de devise (cliquez pour afficher l’image de taille complète)

Étape 2 : InterdictionNULL UnitPrices

Bien que la base de données soit configurée pour autoriser NULL les valeurs dans la colonne de UnitPrice la Products table, nous pouvons empêcher les utilisateurs de visiter cette page particulière de spécifier une NULL UnitPrice valeur. Autrement dit, si un utilisateur ne parvient pas à entrer une UnitPrice valeur lors de la modification d’une ligne de produit, au lieu d’enregistrer les résultats dans la base de données, nous voulons afficher un message informant l’utilisateur que, via cette page, tous les produits modifiés doivent avoir un prix spécifié.

L’objet GridViewUpdateEventArgs passé dans le gestionnaire d’événements RowUpdating de GridView contient une Cancel propriété qui, si elle est définie true, met fin au processus de mise à jour. Étendons le RowUpdating gestionnaire d’événements pour définir true e.Cancel et afficher un message expliquant pourquoi si la UnitPrice valeur de la NewValues collection est null.

Commencez par ajouter un contrôle Web Label à la page nommée MustProvideUnitPriceMessage. Ce contrôle Label s’affiche si l’utilisateur ne parvient pas à spécifier une UnitPrice valeur lors de la mise à jour d’un produit. Définissez la propriété de Text l’étiquette sur « Vous devez fournir un prix pour le produit ». J’ai également créé une classe CSS nommée Styles.css Warning avec la définition suivante :

.Warning
{
    color: Red;
    font-style: italic;
    font-weight: bold;
    font-size: x-large;
}

Enfin, définissez la propriété de CssClass l’étiquette sur Warning. À ce stade, le Concepteur doit afficher le message d’avertissement dans une taille de police rouge, en gras, italique, extra large au-dessus de GridView, comme illustré dans la figure 12.

Une étiquette a été ajoutée au-dessus de GridView

Figure 12 : Une étiquette a été ajoutée au-dessus de GridView (cliquez pour afficher l’image de taille complète)

Par défaut, cette étiquette doit être masquée. Définissez donc sa Visible propriété false sur dans le Page_Load gestionnaire d’événements :

protected void Page_Load(object sender, EventArgs e)
{
    MustProvideUnitPriceMessage.Visible = false;
}

Si l’utilisateur tente de mettre à jour un produit sans spécifier le UnitPrice, nous voulons annuler la mise à jour et afficher l’étiquette d’avertissement. Augmentez le gestionnaire d’événements RowUpdating de GridView comme suit :

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    if (e.NewValues["UnitPrice"] != null)
    {
        e.NewValues["UnitPrice"] =
            decimal.Parse(e.NewValues["UnitPrice"].ToString(),
                System.Globalization.NumberStyles.Currency);
    }
    else
    {
        // Show the Label
        MustProvideUnitPriceMessage.Visible = true;

        // Cancel the update
        e.Cancel = true;
    }
}

Si un utilisateur tente d’enregistrer un produit sans spécifier de prix, la mise à jour est annulée et un message utile s’affiche. Bien que la base de données (et la logique métier) autorise NULL UnitPrice s, cette page ASP.NET particulière ne le fait pas.

Un utilisateur ne peut pas laisser unitPrice vide

Figure 13 : Un utilisateur ne peut pas laisser UnitPrice vide (cliquez pour afficher l’image de taille complète)

Jusqu’à présent, nous avons vu comment utiliser l’événement GridView pour modifier par programmation les valeurs de RowUpdating paramètre affectées à la collection ObjectDataSource UpdateParameters , ainsi que comment annuler complètement le processus de mise à jour. Ces concepts portent sur les contrôles DetailsView et FormView et s’appliquent également à l’insertion et à la suppression.

Ces tâches peuvent également être effectuées au niveau ObjectDataSource par le biais de gestionnaires d’événements pour ses événements et UpdatingDeleting ses Insertingévénements. Ces événements se déclenchent avant l’appel de la méthode associée de l’objet sous-jacent et fournissent une dernière chance de modifier la collection de paramètres d’entrée ou d’annuler l’opération. Les gestionnaires d’événements pour ces trois événements sont passés à un objet de type ObjectDataSourceMethodEventArgs qui a deux propriétés d’intérêt :

  • Annuler, qui, s’il est défini sur true, annule l’opération en cours d’exécution
  • InputParameters, qui est la collection de InsertParameters, UpdateParametersou DeleteParameters, selon que le gestionnaire d’événements est pour le Inserting, Updatingou Deleting l’événement

Pour illustrer l’utilisation des valeurs de paramètre au niveau ObjectDataSource, incluons un DetailsView dans notre page qui permet aux utilisateurs d’ajouter un nouveau produit. Ce DetailsView sera utilisé pour fournir une interface permettant d’ajouter rapidement un nouveau produit à la base de données. Pour conserver une interface utilisateur cohérente lors de l’ajout d’un nouveau produit, nous allons autoriser l’utilisateur à entrer uniquement des valeurs pour les champs et UnitPrice les ProductName champs. Par défaut, ces valeurs qui ne sont pas fournies dans l’interface d’insertion de DetailsView sont définies sur une NULL valeur de base de données. Toutefois, nous pouvons utiliser l’événement Inserting ObjectDataSource pour injecter différentes valeurs par défaut, comme nous le verrons bientôt.

Étape 3 : Fournir une interface pour ajouter de nouveaux produits

Faites glisser un DetailsView à partir de la boîte à outils sur le Concepteur au-dessus de GridView, effacez ses Height propriétés et Width liez-le à l’ObjetDataSource déjà présent sur la page. Cela ajoute un Objet BoundField ou CheckBoxField pour chacun des champs du produit. Étant donné que nous voulons utiliser ce DetailsView pour ajouter de nouveaux produits, nous devons vérifier l’option Activer l’insertion à partir de la balise active ; Toutefois, il n’existe aucune option de ce type, car la méthode ObjectDataSource n’est Insert() pas mappée à une méthode dans la ProductsBLL classe (rappelez-vous que nous définissons ce mappage sur (None) lors de la configuration de la source de données voir la figure 3.

Pour configurer ObjectDataSource, sélectionnez le lien Configurer la source de données à partir de sa balise active, en lançant l’Assistant. Le premier écran vous permet de modifier l’objet sous-jacent auquel ObjectDataSource est lié ; laissez la valeur définie sur ProductsBLL. L’écran suivant répertorie les mappages des méthodes ObjectDataSource aux objets sous-jacents. Même si nous avons explicitement indiqué que les méthodes et Delete() les Insert() méthodes ne doivent pas être mappées à des méthodes, si vous accédez aux onglets INSERT et DELETE, vous verrez qu’un mappage est là. Cela est dû au fait que les ProductsBLLméthodes et DeleteProduct les AddProduct méthodes utilisent l’attribut DataObjectMethodAttribute pour indiquer qu’ils sont les méthodes par défaut pour Insert() et Delete(), respectivement. Par conséquent, l’Assistant ObjectDataSource les sélectionne chaque fois que vous exécutez l’Assistant, sauf s’il existe une autre valeur explicitement spécifiée.

Laissez la Insert() méthode pointer vers la AddProduct méthode, mais définissez à nouveau la liste déroulante de l’onglet DELETE sur (Aucun).

Définir la liste déroulante de l’onglet INSERT sur la méthode AddProduct

Figure 14 : Définir la liste déroulante de l’onglet INSERT sur la AddProduct méthode (Cliquez pour afficher l’image de taille complète)

Définir la liste déroulante de l’onglet DELETE sur (Aucun)

Figure 15 : Définir la liste déroulante de l’onglet DELETE sur (Aucun) (cliquez pour afficher l’image de taille complète)

Après avoir apporté ces modifications, la syntaxe déclarative de ObjectDataSource sera développée pour inclure une InsertParameters collection, comme indiqué ci-dessous :

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
    InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="quantityPerUnit" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="unitsInStock" Type="Int16" />
        <asp:Parameter Name="unitsOnOrder" Type="Int16" />
        <asp:Parameter Name="reorderLevel" Type="Int16" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
    </InsertParameters>
</asp:ObjectDataSource>

Réexécuter l’Assistant a ajouté la OldValuesParameterFormatString propriété. Prenez un moment pour effacer cette propriété en la définissant sur la valeur par défaut ({0}) ou en la supprimant complètement de la syntaxe déclarative.

Avec objectDataSource fournissant des fonctionnalités d’insertion, la balise active detailsView inclut désormais la case Activer l’insertion ; revenez au Concepteur et cochez cette option. Ensuite, analysez le DetailsView afin qu’il ait uniquement deux BoundFields - ProductName et UnitPrice - et CommandField. À ce stade, la syntaxe déclarative de DetailsView doit ressembler à ceci :

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Fields>
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
        <asp:CommandField ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

La figure 16 montre cette page lorsqu’elle est consultée via un navigateur à ce stade. Comme vous pouvez le voir, DetailsView répertorie le nom et le prix du premier produit (Chai). Toutefois, nous voulons une interface d’insertion qui permet à l’utilisateur d’ajouter rapidement un nouveau produit à la base de données.

DetailsView est actuellement rendu en mode lecture seule

Figure 16 : Le DetailsView est actuellement rendu en mode lecture seule (cliquez pour afficher l’image de taille complète)

Pour afficher DetailsView en mode d’insertion, nous devons définir la DefaultMode propriété Insertingsur . Cela affiche DetailsView en mode d’insertion lors de sa première visite et le conserve après l’insertion d’un nouvel enregistrement. Comme le montre la figure 17, un tel DetailsView fournit une interface rapide pour l’ajout d’un nouvel enregistrement.

DetailsView fournit une interface permettant d’ajouter rapidement un nouveau produit

Figure 17 : DetailsView fournit une interface permettant d’ajouter rapidement un nouveau produit (cliquez pour afficher l’image de taille complète)

Lorsque l’utilisateur entre un nom de produit et un prix (par exemple, « Acme Water » et 1,99, comme dans la figure 17), puis clique sur Insérer, un postback se produit et le flux de travail d’insertion commence, ce qui aboutit à l’ajout d’un nouvel enregistrement de produit à la base de données. DetailsView conserve son interface d’insertion et gridView est automatiquement rebondi à sa source de données afin d’inclure le nouveau produit, comme illustré dans la figure 18.

Produit

Figure 18 : Le produit « Acme Water » a été ajouté à la base de données

Bien que gridView dans la figure 18 ne l’affiche pas, les champs de produit qui manquent de l’interface CategoryIDDetailsView, SupplierIDQuantityPerUnitet ainsi de suite sont affectés NULL aux valeurs de base de données. Pour ce faire, procédez comme suit :

  1. Accéder à l’Explorateur de serveurs dans Visual Studio
  2. Développement du NORTHWND.MDF nœud de base de données
  3. Cliquez avec le bouton droit sur le nœud de Products la table de base de données
  4. Sélectionner Afficher les données de table

Cela répertorie tous les enregistrements de la Products table. Comme le montre la figure 19, toutes les colonnes de notre nouveau produit autres que ProductID, ProductNameet UnitPrice ont NULL des valeurs.

Les champs de produit non fournis dans DetailsView sont des valeurs NULL affectées

Figure 19 : Les champs de produit non fournis dans DetailsView sont des valeurs attribuées NULL (Cliquez pour afficher l’image de taille complète)

Nous pouvons fournir une valeur par défaut autre que NULL pour une ou plusieurs de ces valeurs de colonne, car NULL n’est pas la meilleure option par défaut ou parce que la colonne de base de données elle-même n’autorise NULL pas. Pour ce faire, nous pouvons définir par programmation les valeurs des paramètres de la collection DetailsView InputParameters . Cette affectation peut être effectuée dans le gestionnaire d’événements de l’événement DetailsView ItemInserting ou dans Inserting l’événement ObjectDataSource. Étant donné que nous avons déjà examiné l’utilisation des événements de pré-niveau et de post-niveau au niveau du contrôle Web de données, nous allons explorer à l’aide des événements ObjectDataSource cette fois.

Étape 4 : Affectation de valeurs aux paramètres etSupplierIDauxCategoryIDparamètres

Pour ce tutoriel, imaginons que pour notre application lors de l’ajout d’un nouveau produit via cette interface, il doit être attribué une valeur et SupplierID une CategoryID valeur de 1. Comme mentionné précédemment, ObjectDataSource a une paire d’événements de pré-niveau et de post-niveau qui se déclenchent pendant le processus de modification des données. Lorsque sa Insert() méthode est appelée, ObjectDataSource déclenche d’abord son Inserting événement, puis appelle la méthode à laquelle sa Insert() méthode a été mappée, puis déclenche enfin l’événement Inserted . Le Inserting gestionnaire d’événements nous offre une dernière occasion d’ajuster les paramètres d’entrée ou d’annuler l’opération en bloc.

Remarque

Dans une application réelle, vous voudriez probablement laisser l’utilisateur spécifier la catégorie et le fournisseur ou choisir cette valeur pour eux en fonction de certains critères ou logique métier (plutôt que de sélectionner aveuglement un ID de 1). Quel que soit l’exemple, l’exemple montre comment définir par programmation la valeur d’un paramètre d’entrée à partir de l’événement de pré-niveau de ObjectDataSource.

Prenez un moment pour créer un gestionnaire d’événements pour l’événement Inserting ObjectDataSource. Notez que le deuxième paramètre d’entrée du gestionnaire d’événements est un objet de type ObjectDataSourceMethodEventArgs, qui a une propriété pour accéder à la collection de paramètres (InputParameters) et une propriété pour annuler l’opération (Cancel).

protected void ObjectDataSource1_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{

}

À ce stade, la InputParameters propriété contient la collection ObjectDataSource InsertParameters avec les valeurs affectées à partir de DetailsView. Pour modifier la valeur de l’un de ces paramètres, utilisez simplement : e.InputParameters["paramName"] = value. Par conséquent, pour définir les valeurs 1 et SupplierID les CategoryID valeurs, ajustez le Inserting gestionnaire d’événements comme suit :

protected void ObjectDataSource1_Inserting
    (object sender, ObjectDataSourceMethodEventArgs e)
{
    e.InputParameters["CategoryID"] = 1;
    e.InputParameters["SupplierID"] = 1;
}

Cette fois lors de l’ajout d’un nouveau produit (par exemple Acme Soda), les colonnes et SupplierID les CategoryID colonnes du nouveau produit sont définies sur 1 (voir la figure 20).

Les nouveaux produits ont désormais leurs valeurs CategoryID et SupplierID définies sur 1

Figure 20 : Les nouveaux produits ont maintenant leur CategoryID valeur définie SupplierID sur 1 (Cliquez pour afficher l’image de taille complète)

Résumé

Pendant la modification, l’insertion et la suppression du processus, le contrôle Web de données et ObjectDataSource passent par un certain nombre d’événements de pré-niveau et de post-niveau. Dans ce tutoriel, nous avons examiné les événements de pré-niveau et vu comment les utiliser pour personnaliser les paramètres d’entrée ou annuler l’opération de modification des données à la fois à partir du contrôle Web de données et des événements ObjectDataSource. Dans le tutoriel suivant, nous allons examiner la création et l’utilisation de gestionnaires d’événements pour les événements de post-niveau.

Bonne programmation !

À propos de l’auteur

Scott Mitchell, auteur de sept livres ASP/ASP.NET et fondateur de 4GuysFromRolla.com, travaille avec les technologies Web Microsoft depuis 1998. Scott travaille en tant que consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 en 24 heures. Il peut être accessible à mitchell@4GuysFromRolla.com. ou via son blog, qui peut être trouvé à http://ScottOnWriting.NET.

Merci spécial à

Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. Les réviseurs principaux de ce tutoriel étaient Jackie Goor et Liz Shulok. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.