Interrogation des données avec le contrôle SqlDataSource (C#)
par Scott Mitchell
Dans les didacticiels précédents, nous avons utilisé le contrôle ObjectDataSource pour séparer complètement la couche de présentation de la couche Accès aux données. À partir de ce tutoriel, nous apprenons comment le contrôle SqlDataSource peut être utilisé pour les applications simples qui ne nécessitent pas une séparation aussi stricte de la présentation et de l’accès aux données.
Introduction
Tous les tutoriels que nous avons examinés jusqu’à présent ont utilisé une architecture hiérarchisé composée de couches présentation, logique métier et accès aux données. La couche d’accès aux données (DAL) a été conçue dans le premier tutoriel (Création d’une couche d’accès aux données) et de la couche logique métier dans la deuxième (création d’une couche logique métier). À compter du didacticiel Affichage des données avec objectDataSource , nous avons vu comment utiliser ASP.NET nouveau contrôle ObjectDataSource de ASP.NET 2.0 pour interface déclarative avec l’architecture de la couche de présentation.
Bien que tous les didacticiels aient déjà utilisé l’architecture pour travailler avec des données, il est également possible d’accéder, d’insérer, de mettre à jour et de supprimer des données de base de données directement à partir d’une page ASP.NET, en contournant l’architecture. Cela place les requêtes de base de données et la logique métier spécifiques directement dans la page web. Pour les applications suffisamment volumineuses ou complexes, la conception, l’implémentation et l’utilisation d’une architecture hiérarchisée sont essentielles pour la réussite, la fiabilité et la maintenance de l’application. Toutefois, le développement d’une architecture robuste peut être inutile lors de la création d’applications extrêmement simples et ponctuelles.
ASP.NET 2.0 fournit cinq contrôles de source de données intégrés SqlDataSource, AccessDataSource, ObjectDataSource, XmlDataSource et SiteMapDataSource. SqlDataSource peut être utilisé pour accéder aux données et les modifier directement à partir d’une base de données relationnelle, notamment Microsoft SQL Server, Microsoft Access, Oracle, MySQL et d’autres. Dans ce tutoriel et les trois suivants, nous allons examiner comment utiliser le contrôle SqlDataSource, explorer comment interroger et filtrer des données de base de données, ainsi que comment utiliser SqlDataSource pour insérer, mettre à jour et supprimer des données.
Figure 1 : ASP.NET 2.0 inclut cinq contrôles de source de données intégrés
Comparaison de ObjectDataSource et SqlDataSource
Conceptuellement, les contrôles ObjectDataSource et SqlDataSource sont simplement des proxys vers des données. Comme indiqué dans le didacticiel Displaying Data With the ObjectDataSource, ObjectDataSource a des propriétés qui indiquent le type d’objet qui fournit les données et les méthodes à appeler pour sélectionner, insérer, mettre à jour et supprimer des données du type d’objet sous-jacent. Une fois les propriétés ObjectDataSource configurées, un contrôle Web de données tel qu’un GridView, DetailsView ou DataList peut être lié au contrôle, à l’aide de ObjectDataSource s Select()
, Insert()
Delete()
et Update()
des méthodes pour interagir avec l’architecture sous-jacente.
SqlDataSource fournit les mêmes fonctionnalités, mais fonctionne sur une base de données relationnelle plutôt qu’une bibliothèque d’objets. Avec SqlDataSource, nous devons spécifier la base de données chaîne de connexion et les requêtes SQL ad hoc ou les procédures stockées à exécuter pour insérer, mettre à jour, supprimer et récupérer des données. SqlDataSource s Select()
, Insert()
, Update()
et Delete()
méthodes, lorsqu’elles sont appelées, se connectent à la base de données spécifiée et émettent la requête SQL appropriée. Comme l’illustre le diagramme suivant, ces méthodes effectuent le travail de grunt de connexion à une base de données, d’émission d’une requête et de renvoi des résultats.
Figure 2 : SqlDataSource sert de proxy à la base de données
Remarque
Dans ce tutoriel, nous allons nous concentrer sur la récupération de données à partir de la base de données. Dans le didacticiel insertion, mise à jour et suppression de données avec le didacticiel Contrôle SqlDataSource, nous allons voir comment configurer SqlDataSource pour prendre en charge l’insertion, la mise à jour et la suppression.
Contrôles SqlDataSource et AccessDataSource
Outre le contrôle SqlDataSource, ASP.NET 2.0 inclut également un contrôle AccessDataSource. Ces deux contrôles différents mènent de nombreux développeurs nouveaux à ASP.NET 2.0 pour soupçonner que le contrôle AccessDataSource est conçu pour fonctionner exclusivement avec Microsoft Access avec le contrôle SqlDataSource conçu pour fonctionner exclusivement avec Microsoft SQL Server. Bien que AccessDataSource soit conçu pour fonctionner spécifiquement avec Microsoft Access, le contrôle SqlDataSource fonctionne avec n’importe quelle base de données relationnelle accessible via .NET. Cela inclut tous les magasins de données compatibles OleDb ou ODBC, tels que Microsoft SQL Server, Microsoft Access, Oracle, Informix, MySQL et PostgreSQL, entre autres.
La seule différence entre les contrôles AccessDataSource et SqlDataSource est la façon dont les informations de connexion de base de données sont spécifiées. Le contrôle AccessDataSource a besoin uniquement du chemin d’accès au fichier de base de données Access. SqlDataSource, en revanche, nécessite une chaîne de connexion complète.
Étape 1 : Création des pages web SqlDataSource
Avant de commencer à explorer comment utiliser directement les données de base de données à l’aide du contrôle SqlDataSource, prenons d’abord un moment pour créer les pages ASP.NET dans notre projet de site web dont nous aurons besoin pour ce didacticiel et les trois suivants. Commencez par ajouter un nouveau dossier nommé SqlDataSource
. Ensuite, ajoutez les ASP.NET pages suivantes à ce dossier, en veillant à associer chaque page à la Site.master
page maître :
Default.aspx
Querying.aspx
ParameterizedQueries.aspx
InsertUpdateDelete.aspx
OptimisticConcurrency.aspx
Figure 3 : Ajouter les pages ASP.NET pour les didacticiels liés à SqlDataSource
Comme dans les autres dossiers, Default.aspx
dans le SqlDataSource
dossier répertorie les didacticiels de sa section. Rappelez-vous que le SectionLevelTutorialListing.ascx
contrôle utilisateur fournit cette fonctionnalité. Par conséquent, ajoutez ce contrôle utilisateur en Default.aspx
le faisant glisser de l’Explorateur de solutions vers l’affichage Création de la page.
Figure 4 : Ajouter le contrôle utilisateur à Default.aspx
(cliquez pour afficher l’image SectionLevelTutorialListing.ascx
de taille complète)
Enfin, ajoutez ces quatre pages en tant qu’entrées au Web.sitemap
fichier. Plus précisément, ajoutez le balisage suivant après l’ajout de boutons personnalisés à la liste de données et au répéteur <siteMapNode>
:
<siteMapNode url="~/SqlDataSource/Default.aspx"
title="Using the SqlDataSource Control"
description="Work directly with database data using the SqlDataSource control.">
<siteMapNode url="~/SqlDataSource/Querying.aspx" title="Retrieving Database Data"
description="Examines how to query data from a database that can then be
displayed through a data Web control."/>
<siteMapNode url="~/SqlDataSource/ParameterizedQueries.aspx"
title="Parameterized Queries"
description="Learn how to specify parameterized WHERE clauses in the
SqlDataSource's SELECT statement." />
<siteMapNode url="~/SqlDataSource/InsertUpdateDelete.aspx"
title="Inserting, Updating, and Deleting Database Data"
description="See how to configure the SqlDataSource to include INSERT, UPDATE,
and DELETE statements." />
<siteMapNode url="~/SqlDataSource/OptimisticConcurrency.aspx"
title="Using Optimistic Concurrency"
description="Explore how to augment the SqlDataSource to include support for
optimistic concurrency." />
</siteMapNode>
Après la mise à jour Web.sitemap
, prenez un moment pour afficher le site web des didacticiels via un navigateur. Le menu de gauche inclut désormais des éléments pour les didacticiels d’édition, d’insertion et de suppression.
Figure 5 : La carte de site inclut désormais des entrées pour les didacticiels SqlDataSource
Étape 2 : Ajout et configuration du contrôle SqlDataSource
Commencez par ouvrir la Querying.aspx
page dans le dossier et basculez vers l’affichage SqlDataSource
Création. Faites glisser un contrôle SqlDataSource de la boîte à outils sur le Concepteur et définissez-le ID
ProductsDataSource
sur . Comme avec ObjectDataSource, SqlDataSource ne produit aucune sortie rendue et apparaît donc sous forme de zone grise sur l’aire de conception. Pour configurer SqlDataSource, cliquez sur le lien Configurer la source de données à partir de la balise active sqlDataSource.
Figure 6 : Cliquez sur le lien Configurer la source de données à partir de la balise active sqlDataSource
Cela affiche l’Assistant Configurer la source de données du contrôle SqlDataSource. Bien que les étapes de l’Assistant diffèrent des contrôles ObjectDataSource, l’objectif final est le même pour fournir les détails sur la façon de récupérer, insérer, mettre à jour et supprimer des données via la source de données. Pour SqlDataSource, cela implique de spécifier la base de données sous-jacente à utiliser et de fournir les instructions SQL ad hoc ou les procédures stockées.
La première étape de l’Assistant nous invite à entrer la base de données. La liste déroulante inclut les bases de données trouvées dans le dossier de l’application App_Data
web et celles qui ont été ajoutées au nœud Connexions de données dans l’Explorateur de serveurs. Étant donné que nous avons déjà ajouté une chaîne de connexion pour la NORTHWIND.MDF
base de données dans le App_Data
fichier de Web.config
notre projet, la liste déroulante inclut une référence à ce chaîne de connexion. NORTHWINDConnectionString
Choisissez cet élément dans la liste déroulante, puis cliquez sur Suivant.
Figure 7 : Choisir dans NORTHWINDConnectionString
la liste déroulante
Après avoir choisi la base de données, l’Assistant demande à la requête de retourner des données. Nous pouvons spécifier les colonnes d’une table ou d’une vue à retourner ou entrer une instruction SQL personnalisée ou spécifier une procédure stockée. Vous pouvez basculer entre ce choix via l’instruction Spécifier une instruction SQL personnalisée ou une procédure stockée et spécifier des colonnes à partir d’une case d’option de table ou d’affichage.
Remarque
Pour ce premier exemple, nous allons utiliser l’option Spécifier des colonnes à partir d’une table ou d’une vue. Nous allons revenir à l’Assistant plus loin dans ce didacticiel et explorer l’option Spécifier une instruction SQL personnalisée ou une procédure stockée.
La figure 8 montre l’écran Configurer l’instruction Select lorsque la case d’option Spécifier des colonnes à partir d’une table ou d’une vue est sélectionnée. La liste déroulante contient l’ensemble de tables et de vues dans la base de données Northwind, avec les colonnes de la table ou des vues sélectionnées affichées dans la liste à cocher ci-dessous. Pour cet exemple, renvoyons les colonnes et UnitPrice
les ProductID
ProductName
colonnes de la Products
table. Comme le montre la figure 8, après avoir effectué ces sélections, l’Assistant affiche l’instruction SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]
SQL résultante.
Figure 8 : Retourner des données de la Products
table
Une fois que vous avez configuré l’Assistant pour retourner les colonnes ProductName
et UnitPrice
les ProductID
colonnes de la Products
table, cliquez sur le bouton Suivant. Cet écran final permet d’examiner les résultats de la requête configurée à l’étape précédente. Cliquez sur le bouton Tester la requête pour exécuter l’instruction configurée SELECT
et affiche les résultats dans une grille.
Figure 9 : Cliquez sur le bouton Tester la requête pour passer en revue votre SELECT
requête
Pour mettre fin à l'Assistant, cliquez sur Terminer.
Comme avec ObjectDataSource, l’Assistant SqlDataSource affecte simplement des valeurs aux propriétés du contrôle, à savoir les ConnectionString
propriétés et SelectCommand
les propriétés. Une fois l’Assistant terminé, le balisage déclaratif de votre contrôle SqlDataSource doit ressembler à ce qui suit :
<asp:SqlDataSource ID="ProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>
La ConnectionString
propriété fournit des informations sur la connexion à la base de données. Cette propriété peut être affectée à une valeur de chaîne de connexion complète et codée en dur ou peut pointer vers un chaîne de connexion dans Web.config
. Pour référencer une valeur chaîne de connexion dans Web.config, utilisez la syntaxe <%$ expressionPrefix:expressionValue %>
. En règle générale, expressionPrefix est ConnectionStrings et expressionValue est le nom de la chaîne de connexion dans la<connectionStrings>
Web.config
section. Toutefois, la syntaxe peut être utilisée pour référencer <appSettings>
des éléments ou du contenu à partir de fichiers de ressources. Pour plus d’informations sur cette syntaxe, consultez ASP.NET Vue d’ensemble des expressions.
La SelectCommand
propriété spécifie l’instruction SQL ad hoc ou la procédure stockée à exécuter pour retourner les données.
Étape 3 : Ajout d’un contrôle Web de données et liaison à SqlDataSource
Une fois que SqlDataSource a été configuré, il peut être lié à un contrôle Web de données, tel qu’un GridView ou DetailsView. Pour ce tutoriel, nous allons afficher les données dans un GridView. À partir de la boîte à outils, faites glisser un GridView sur la page et liez-le à ProductsDataSource
SqlDataSource en choisissant la source de données dans la liste déroulante de la balise active gridView.
Figure 10 : Ajouter un GridView et le lier au contrôle SqlDataSource (cliquez pour afficher l’image de taille complète)
Une fois que vous avez sélectionné le contrôle SqlDataSource dans la liste déroulante de la balise active GridView, Visual Studio ajoute automatiquement un Objet BoundField ou CheckBoxField à GridView pour chacune des colonnes retournées par le contrôle de source de données. Étant donné que SqlDataSource retourne trois colonnes ProductID
de base de données, ProductName
et UnitPrice
qu’il existe trois champs dans GridView.
Prenez un moment pour configurer les trois BoundFields de GridView. Remplacez la ProductName
propriété du HeaderText
champ par Nom du produit et par UnitPrice
Prix. Mettez également le UnitPrice
champ en forme de devise. Après avoir apporté ces modifications, le balisage déclaratif de GridView doit ressembler à ce qui suit :
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="Product Name"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" DataFormatString="{0:c}"
HtmlEncode="False" />
</Columns>
</asp:GridView>
Visitez cette page via un navigateur. Comme le montre la figure 11, GridView répertorie chaque produit ProductID
, ProductName
et UnitPrice
les valeurs.
Figure 11 : GridView affiche chaque produit ProductID
, ProductName
et UnitPrice
valeurs (cliquez pour afficher l’image de taille complète)
Lorsque la page est visitée, GridView appelle sa méthode de contrôle de source de Select()
données. Lorsque nous utilisions le contrôle ObjectDataSource, il s’agissait de la ProductsBLL
méthode s de GetProducts()
classe. Toutefois, avec SqlDataSource, la Select()
méthode établit une connexion à la base de données spécifiée et émet le SelectCommand
(SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]
dans cet exemple). SqlDataSource retourne ses résultats que GridView énumère, créant une ligne dans GridView pour chaque enregistrement de base de données retourné.
Fonctionnalités de contrôle web de données intégrées et contrôle SqlDataSource
En général, les fonctionnalités inhérentes aux contrôles Web de données paginent, trient, modifient, suppriment, insèrent, et ainsi de suite sont spécifiques au contrôle Web de données et ne dépendent pas du contrôle de source de données utilisé. Autrement dit, GridView peut utiliser sa pagination intégrée, son tri, sa modification et sa suppression, qu’elle soit liée à un ObjectDataSource ou à sqlDataSource. Toutefois, certaines fonctionnalités de contrôle Web de données sont sensibles au contrôle de source de données utilisé ou à la configuration du contrôle de code source de données.
Par exemple, dans le didacticiel Sur la pagination efficace via de grandes quantités de données , nous avons abordé comment, par défaut, la logique de pagination des contrôles Web de données retourne naivement tous les enregistrements de la source de données sous-jacente, puis affiche uniquement le sous-ensemble approprié d’enregistrements en fonction de l’index de page actuel et du nombre d’enregistrements à afficher par page. Ce modèle est très inefficace lors de la pagination par le biais de jeux de résultats suffisamment volumineux. Heureusement, ObjectDataSource peut être configuré pour prendre en charge la pagination personnalisée, qui retourne uniquement le sous-ensemble précis d’enregistrements à afficher. Toutefois, le contrôle SqlDataSource ne possède pas les propriétés permettant d’implémenter la pagination personnalisée.
Une autre subtilité avec la pagination et le tri se produit avec SqlDataSource. Par défaut, les données retournées à partir d’une SqlDataSource peuvent être paginées ou triées via GridView. Pour illustrer cela, vérifiez les options Activer la pagination et Activer le tri dans la balise Querying.aspx
active gridView et vérifiez que cela fonctionne comme prévu.
Le tri et la pagination fonctionnent, car SqlDataSource récupère les données de base de données dans un DataSet faiblement typé. Le nombre total d’enregistrements retournés par la requête constitue un aspect essentiel de l’implémentation de la pagination à partir du DataSet. En outre, les résultats de DataSet peuvent être triés par le biais d’un DataView. Ces fonctionnalités sont automatiquement utilisées par SqlDataSource lorsque les requêtes GridView sont paginées ou triées.
SqlDataSource peut être configuré pour renvoyer un DataReader au lieu d’un DataSet en remplaçant sa DataSourceMode
propriété ( DataSet
par défaut) DataReader
par . L’utilisation d’un DataReader peut être préférée dans les situations où vous transmettez les résultats de SqlDataSource au code existant qui attend un DataReader. De plus, étant donné que les DataReaders sont considérablement plus simples que les DataSets, ils offrent de meilleures performances. Si vous apportez cette modification, toutefois, le contrôle Web de données ne peut ni trier ni page, car SqlDataSource ne peut pas déterminer le nombre d’enregistrements retournés par la requête, ni dataReader n’offre aucune technique pour trier les données retournées.
Étape 4 : Utilisation d’une instruction SQL personnalisée ou d’une procédure stockée
Lors de la configuration du contrôle SqlDataSource, la requête utilisée pour retourner des données peut être spécifiée dans l’une des deux approches en tant qu’instruction SQL personnalisée ou procédure stockée, ou en tant que colonnes d’une table ou d’une vue existante. À l’étape 2, nous avons examiné la sélection de colonnes dans la Products
table. Examinons l’utilisation d’une instruction SQL personnalisée.
Ajoutez un autre contrôle GridView à la Querying.aspx
page et choisissez de créer une source de données à partir de la liste déroulante dans la balise active. Ensuite, indiquez que les données seront extraites d’une base de données, ce qui créera un contrôle SqlDataSource. Nommez le contrôle ProductsWithCategoryInfoDataSource
.
Figure 12 : Créer un contrôle SqlDataSource nommé ProductsWithCategoryInfoDataSource
L’écran suivant nous demande de spécifier la base de données. Comme nous l’avons fait dans la figure 7, sélectionnez-le NORTHWINDConnectionString
dans la liste déroulante, puis cliquez sur Suivant. Dans l’écran Configurer l’instruction Select, choisissez la case d’option Spécifier une instruction SQL personnalisée ou une case d’option de procédure stockée, puis cliquez sur Suivant. Cela affiche l’écran Définir des instructions personnalisées ou des procédures stockées, qui propose des onglets étiquetés SELECT, UPDATE, INSERT et DELETE. Dans chaque onglet, vous pouvez entrer une instruction SQL personnalisée dans la zone de texte ou choisir une procédure stockée dans la liste déroulante. Dans ce tutoriel, nous allons examiner l’entrée d’une instruction SQL personnalisée ; le tutoriel suivant inclut un exemple qui utilise une procédure stockée.
Figure 13 : Entrer une instruction SQL personnalisée ou choisir une procédure stockée
L’instruction SQL personnalisée peut être entrée manuellement dans la zone de texte ou être construite graphiquement en cliquant sur le bouton Générateur de requêtes. À partir du Générateur de requêtes ou de la zone de texte, utilisez la requête suivante pour renvoyer les ProductID
champs de la Products
table à l’aide d’un JOIN
pour récupérer les produits CategoryName
de la Categories
ProductName
table :
SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
FROM Categories
INNER JOIN Products ON
Categories.CategoryID = Products.CategoryID
Figure 14 : Vous pouvez construire graphiquement la requête à l’aide du Générateur de requêtes
Après avoir spécifié la requête, cliquez sur Suivant pour passer à l’écran Requête de test. Cliquez sur Terminer pour terminer l’Assistant SqlDataSource.
Une fois l’Assistant terminé, GridView aura trois BoundFields ajoutés à celui-ci affichant les ProductID
ProductName
colonnes retournées par la requête et CategoryName
résultant du balisage déclaratif suivant :
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsWithCategoryInfoDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
SortExpression="CategoryName" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsWithCategoryInfoDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="
SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
FROM Categories
INNER JOIN Products ON Categories.CategoryID = Products.CategoryID">
</asp:SqlDataSource>
Figure 15 : GridView affiche chaque ID, nom et nom de catégorie associé (cliquez pour afficher l’image de taille complète)
Résumé
Dans ce tutoriel, nous avons vu comment interroger et afficher des données à l’aide du contrôle SqlDataSource. Comme ObjectDataSource, SqlDataSource sert de proxy, fournissant une approche déclarative pour accéder aux données. Ses propriétés spécifient la base de données à laquelle se connecter et la requête SQL SELECT
à exécuter ; elles peuvent être spécifiées via le Fenêtre Propriétés ou à l’aide de l’Assistant Configurer dataSource.
Les SELECT
exemples de requête que nous avons examinés dans ce didacticiel ont retourné tous les enregistrements de la requête spécifiée. Toutefois, le contrôle SqlDataSource peut inclure une WHERE
clause avec des paramètres dont les valeurs sont affectées par programme ou sont automatiquement extraites d’une source spécifiée. Nous allons examiner comment créer et utiliser des requêtes paramétrables dans le tutoriel suivant !
Bonne programmation !
Pour aller plus loin
Pour plus d’informations sur les sujets abordés dans ce tutoriel, consultez les ressources suivantes :
- Vue d’ensemble du contrôle SqlDataSource
- didacticiels de démarrage rapide ASP.NET : Contrôle SqlDataSource
- Élément Web.config
<connectionStrings>
- Référence de chaîne de connexion de base de données
À 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 didacticiel étaient Susan Connery, Bernadette Leigh et David Suru. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.