Les contrôles de source de données sont un nouveau type de contrôle serveur introduit dans Microsoft Visual Studio 2005. Ils constituent un élément clé de l'architecture de liaison de données et peuvent fournir un modèle de programmation déclaratif et un comportement de liaison de données automatique via des contrôles de liaison de données. Cet article et les articles suivants de cette série présenteront les éléments fondamentaux de la mise en œuvre des contrôles de source de données.
Introduction
En bref, un contrôle de source de données résume un magasin de données et certaines opérations qui peuvent être effectuées sur les données contenues. Le contrôle DataBound est associé à un contrôle de source de données via sa propriété DataSourceID. La plupart des magasins de données traditionnels sont tabulaires ou hiérarchiques, et les contrôles des sources de données sont divisés en conséquence. Ce que nous souhaitons introduire ici, c'est le contrôle de source de données au format tabulaire.
Le contrôle de source de données lui-même ne fait pas grand-chose ; toute la logique est encapsulée dans des classes dérivées de DataSourceView. Au moins un DataSourceView doit implémenter la fonction de récupération (c'est-à-dire SELECTing) d'un ensemble de lignes. Il peut fournir la fonction de modification des données (c'est-à-dire INSERT, UPDATE et DELETE) (facultatif). Les contrôles liés aux données peuvent vérifier les ensembles de fonctionnalités activés via diverses propriétés Can???. Le contrôle de source de données lui-même n'est qu'un conteneur pour une ou plusieurs vues portant un nom unique. Par convention, la vue par défaut est accessible par son nom, ou elle peut être vide. La question de savoir si ou quel type de relation existe entre les différentes vues peut être définie de manière appropriée en fonction de la mise en œuvre de chaque contrôle de source de données. Par exemple, un contrôle de source de données peut fournir différentes vues filtrées des mêmes données via différentes vues, ou il peut fournir un ensemble de sous-lignes dans une vue secondaire. Vous pouvez utiliser la propriété DataMember d'un contrôle lié aux données pour sélectionner une vue particulière (si le contrôle de source de données fournit plusieurs vues). Veuillez noter qu'aucun des contrôles de source de données intégrés dans Whidbey n'offre actuellement plusieurs vues.
Enfin, permettez-moi de vous présenter quelques éléments de contenu. Les contrôles de source de données (et leurs vues) implémentent deux ensembles d'API. Le premier ensemble d'API est une interface abstraite définie pour quatre opérations de données courantes qui peuvent être utilisées de manière régulière à partir de n'importe quel contrôle lié aux données. Le deuxième groupe est facultatif, défini en termes de domaine ou de magasin de données qu'il représente, est généralement fortement typé et est destiné aux développeurs d'applications.
Exemple
Dans ces articles, vous implémenterez un WeatherDataSource qui fonctionnera avec l'API XML REST (anglais) fournie par Weather.com (anglais) pour récupérer des informations météorologiques basées sur le code postal. Les contrôles de source de données dérivés sont généralement implémentés en premier.
classe publique WeatherDataSource : DataSourceControl {
chaîne publique statique en lecture seule
CurrentConditionsViewName = "CurrentConditions";
privé WeatherDataSourceView _currentConditionsView;
privé WeatherDataSourceView CurrentConditionsView {
obtenir {
si (_currentConditionsView == null) {
_currentConditionsView = new WeatherDataSourceView(this, CurrentConditionsViewName);
}
retourner _currentConditionsView ;
}
}
chaîne publique ZipCode {
obtenir {
chaîne s = (chaîne)ViewState["ZipCode"];
return (s != null) s : String.Empty;
}
ensemble {
if (String.Compare(valeur, ZipCode,
StringComparison.Ordinal) != 0) {
ViewState["ZipCode"] = valeur ;
CurrentConditionsView.RaiseChangedEvent();
}
}
}
remplacement protégé DataSourceView GetView (string viewName) {
if (String.IsNullOrEmpty(viewName) ||
(String.Compare(viewName, CurrentConditionsViewName,
StringComparison.OrdinalIgnoreCase) == 0)) {
retourner CurrentConditionsView ;
}
lancer un nouveau ArgumentOutOfRangeException("viewName");
}
remplacement protégé ICollection GetViewNames() {
return new string[] { CurrentConditionsViewName } ;
}
Météo publique GetWeather() {
return CurrentConditionView.GetWeather();
}
}
Comme vous pouvez le voir, l'idée de base est d'implémenter GetView pour renvoyer une instance de vue nommée et GetViewNames pour renvoyer l'ensemble des vues disponibles.
Ici, choisissez Dériver de DataSourceControl. Une chose qui n'est pas facile à remarquer est que le contrôle lié aux données recherche en fait l'interface IDataSource et que le contrôle DataSource implémente l'interface en implémentant GetView et GetViewNames. La raison pour laquelle l'interface est nécessaire est de permettre au contrôle de la source de données d'être à la fois tabulaire et hiérarchique (si possible, auquel cas dériver du modèle principal et implémenter un autre modèle comme interface). Deuxièmement, il permet également de convertir d'autres contrôles dans divers scénarios pour doubler la capacité de la source de données. Notez également la propriété publique ZipCode et la méthode GetWeather qui renvoie un objet Weather fortement typé. Cette API convient aux développeurs de pages. Les développeurs de pages n'ont pas besoin de penser à DataSourceControl et DataSourceView.
L'étape suivante consiste à implémenter la vue de la source de données elle-même. Cet exemple particulier fournit uniquement des fonctionnalités de niveau SELECT (qui constituent la configuration minimale requise et la seule fonctionnalité utile dans ce scénario).
classe scellée privée WeatherDataSourceView : DataSourceView {
private WeatherDataSource _owner ;
public WeatherDataSourceView (propriétaire WeatherDataSource, string viewName)
: base (propriétaire, viewName) {
_owner = propriétaire ;
}
remplacement protégé IEnumerable ExecuteSelect(
arguments DataSourceSelectArguments) {
arguments.RaiseUnsupportedCapabilitiesError(this);
Météo WeatherObject = GetWeather();
return new Weather[] {weatherObject} ;
}
Météo interne GetWeather() {
chaîne zipCode = _owner.ZipCode ;
si (zipCode.Length == 0) {
lancer une nouvelle InvalidOperationException();
}
WeatherService WeatherService = new WeatherService(zipCode);
retourner WeatherService.GetWeather();
}
vide interne RaiseChangedEvent() {
OnDataSourceViewChanged(EventArgs.Empty);
}
}
Par défaut, la classe DataSourceView renvoie false à partir de propriétés telles que CanUpdate et renvoie NotSupportedException à partir de Update et des méthodes associées. La seule chose que vous devez faire ici dans WeatherDataSourceView est de remplacer la méthode abstraite ExecuteSelect et de renvoyer un IEnumerable contenant les données météorologiques « sélectionnées ». Dans l'implémentation, une classe d'assistance WeatherService est utilisée, qui utilise simplement un objet WebRequest pour interroger Weather.com (en anglais) en utilisant le code postal sélectionné (rien de spécial à ce sujet).
Vous avez peut-être remarqué qu'ExecuteSelect est marqué comme protégé. Ce que le contrôle lié aux données appelle en réalité est la méthode Select publique (et scellée) transmise dans le rappel. L'implémentation de Select appelle ExecuteSelect et appelle le rappel avec l'instance IEnumerable résultante. Ce modèle est très bizarre. Il y a une raison à cela, qui sera expliquée dans les articles suivants de cette série. Veuillez patienter...
Voici un exemple de cette utilisation :
Code postal : <asp:TextBox runat="server" id="zipCodeTextBox" />
<asp:Button runat="server" onclick="OnLookupButtonClick" Text="Regardez" />
<hr />
<asp:FormView runat="server" DataSourceID="weatherDS">
<Modèle d'élément>
<asp:Label runat="serveur"
Text='<%# Eval("Température", "La température actuelle est de {0}.") %>' />
</Modèle d'élément>
</asp:FormView>
<nk:WeatherDataSource runat="server" id="weatherDS" ZipCode="98052" />
<script runat="server">
private void OnLookupButtonClick (expéditeur de l'objet, EventArgs e) {
WeatherDS.ZipCode = zipCodeTextBox.Text.Trim();
}
</script>
Ce code définit le code postal en réponse à la saisie de l'utilisateur, ce qui amène la source de données à émettre une notification de modification, ce qui oblige le contrôle FormView lié à effectuer une liaison de données et à modifier l'affichage.
Désormais, le code d'accès aux données est encapsulé dans le contrôle de source de données. De plus, ce modèle permet à Weather.com (en anglais) de publier un composant pouvant également encapsuler des détails spécifiques à son service. J'espère que cela fonctionnera. De plus, l'interface de source de données abstraite permet au FormView de fonctionner uniquement avec des données météorologiques.
Dans l’article suivant, vous améliorerez le contrôle de source de données pour gérer automatiquement les modifications apportées à la valeur du filtre (c’est-à-dire le code postal) utilisée pour interroger les données.