Examen des événements associés à l’insertion, à la mise à jour et à la suppression (C#)
par Scott Mitchell
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 :
- GridView remplit ses ObjectDataSource
UpdateParameters
avec le ou les champs d’identification uniques de l’enregistrement modifié (via laDataKeyNames
propriété) ainsi que les valeurs entrées par l’utilisateur - GridView appelle sa méthode ObjectDataSource, qui appelle à son tour la méthode appropriée dans l’objet
Update()
sous-jacent (ProductsDAL.UpdateProduct
dans notre didacticiel précédent) - 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 UpdateParameters
des 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.
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 etUnitPrice
desProductName
produits
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
, unitPrice
et 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 unitPrice
et productID
les productName
paramè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.
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.
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.
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.
Figure 5 : GridView ajoute des paramètres à la collection ObjectDataSource (cliquez pour afficher l’image UpdateParameters
de 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é true
de 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.
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é false
GridView EnableViewState
sur , vous risquez d’avoir des utilisateurs simultanés à supprimer ou modifier involontairement des enregistrements.
Amélioration de laUnitPrice
mise 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é false
sur .
Figure 7 : Définir les propriétés et HtmlEncode
les DataFormatString
propriétés en conséquence (cliquez pour afficher l’image UnitPrice
de 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.
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
.
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.
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 UnitPrice
par 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.
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.
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.
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 Updating
Deleting
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
,UpdateParameters
ouDeleteParameters
, selon que le gestionnaire d’événements est pour leInserting
,Updating
ouDeleting
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 ProductsBLL
mé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).
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)
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.
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é Inserting
sur . 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.
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.
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 CategoryID
DetailsView, SupplierID
QuantityPerUnit
et ainsi de suite sont affectés NULL
aux valeurs de base de données. Pour ce faire, procédez comme suit :
- Accéder à l’Explorateur de serveurs dans Visual Studio
- Développement du
NORTHWND.MDF
nœud de base de données - Cliquez avec le bouton droit sur le nœud de
Products
la table de base de données - 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
, ProductName
et UnitPrice
ont NULL
des valeurs.
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 etSupplierID
auxCategoryID
paramè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).
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.