Patrice Lamarche
Créer des contrôles sources de données (DataSource objects) avec ASP.net 2
Développement d'un contrôle DataSource qui permet d'effectuer du databinding avec des photos du site Flickr.
Par Patrice Lamarche publié le 19/08/2007 à 23:05, lu 7252 fois, 6 pages
 3 | Création du contrôle source de données
Comme tout bon site web 2.0 qui se respecte, Flickr propose un ensemble d'API qui permet de bâtir tout type d'application utilisant les services fournis par le site de publication de photo. Le seul pré-requis pour pouvoir utiliser ces API est de demander une clé d'utilisation que vous devrez fournir lors de l'utilisation des API. Afin de demander cette clé gratuite pour une utilisation non-commerciale, connectez-vous avec votre compte Flickr et rendez-vous sur la page services : http://www.flickr.com/services
Afin de ne pas avoir à implémenter cet API nous-même, nous allons utiliser une libraire managée Open Source disponible sur CodePlex : FlickrNet disponible à cette adresse http://www.codeplex.com/flickrnet
Utiliser cette librairie est très simple, il suffit d'instancier un objet Flickr en passant en paramètre une clé d'API fournie par Flickr, et de récupérer un set de photos grâce à la méthode PhotosetsGetPhotos. Cette méthode renvoie un tableau d'objets Photo utilisable pour afficher et/ou récupérer les informations liées à ces photos.

public void GetSetPhotos()

 {

    m_flickr = new Flickr(m_apiKey);

    Photoset set = m_flickr.PhotosetsGetPhotos(ViewState["flickrPhotoSetId"].ToString());

    Photo[] setPhotos;

    m_photos = set.PhotoCollection;

 }

Afin de développer un contrôle source de données, il suffit de créer une classe qui implémente l'interface IDataSource. Cependant le framework.net propose une classe abstraite un peu plus riche : la classe DataSourceControl. Cette classe hérite de System.Web.UI.Control et implémente IDataSource ainsi qu'IListSource, et nous allons donc créer une classe qui hérite de cette classe abstraite afin de définir notre classe FlickrDataSource. Cette classe expose différentes propriétés importante pour son fonctionnement tel que l'ID du set de photos qui sera affichée, le nom d'utilisateur qui sera utilisé pour filtrer les sets dans l'interface de configuration. La méthode la plus importante est la méthode GetView. Cette méthode permet de renvoyer une vue de données qui contiendra les donnés pouvant être affichées par le contrôle d'affichage.

    public class FlickrDataSource:DataSourceControl

    {

        private FlickrDataSourceView m_view;

        private Photo[] m_photos;

        private Flickr m_flickr;

        private string m_apiKey;

        private string m_userName;

        private string m_userId;

        private string m_setId;

 

 

public void GetSetPhotos()

        {

            m_flickr = new Flickr(m_apiKey);

            Photoset set = m_flickr.PhotosetsGetPhotos(ViewState["flickrPhotoSetId"].ToString());

            Photo[] setPhotos;

                m_photos = set.PhotoCollection;

        }

 

        public string PhotoSetId

        {

            get

            {

                if (ViewState["flickrPhotoSetId"] !=null)

                    return ViewState["flickrPhotoSetId"].ToString();

                else

                    return m_setId;

 

            }

            set { ViewState["flickrPhotoSetId"] = value;

                m_setId = value;

            }

        }

 

        public string UserName

        {

            get { return m_userName; }

            set 

            { m_userName = value;

            m_flickr = new Flickr(m_apiKey);

            m_userId = m_flickr.PeopleFindByUsername(value).UserId;

            }

        }

 

        public string ApiKey

        {

            get { return m_apiKey; }

            set { m_apiKey = value; }

        }

 

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

        public Photo[] Photos

        {

            get { return m_photos; }

            set { m_photos = value; }

        }

 

 

        protected override DataSourceView GetView(string viewName)

        {

            if (m_view == null)

            {

                m_view = new FlickrDataSourceView(this, viewName);      

            }

            return m_view;

        }

    }

Les données renvoyées qui seront databindés vers des contrôles d'affichage de données tels que des repeater ou datalist doivent être définis dans une vue. Cette vue doit être implémentée grâce à une classe héritant de DataSourceView.
 
/content/5da97713-037d-441d-88ed-51bece6c7028/image2.png
 
DataSourceView expose plusieurs propriétés permettant d'indiquer si votre contrôle source de données supporte la suppression, l'insertion ou encore la modification de données. Les valeurs définies par la classe de base sont définies à false vous devez donc les redéfinir uniquement si vous implémenter ces fonctionnalités afin de renvoyer une valeur true. La classe de base expose également les méthodes permettant d'exécuter ces opérations (ExecuteSelect, ExecuteInsert, etc.), ces méthodes seront appelées durant l'exécution afin de réaliser les opérations correspondantes.
Le FlickrDataSource permettant uniquement d'afficher des données, il est uniquement nécessaire de redéfinir la méthode ExecuteSelect, méthode qui appellera la méthode GetSetPhotos définis dans la classe FlickrDataSource.

namespace FlickrDataSource

{

    class FlickrDataSourceView : DataSourceView

    {

        private FlickrDataSource m_owner;

 

        internal FlickrDataSourceView(FlickrDataSource owner, string viewName)

            : base(owner, viewName)

        {

            m_owner = owner;

        }

 

 

        protected override System.Collections.IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)

        {

            m_owner.GetSetPhotos();

            return m_owner.Photos;

        }

    }

}

La méthode ExecuteSelect doit renvoyer un objet implémentant IEnumerable, nous pouvons donc renvoyer un tableau de photos tel que renvoyé par FlickrNet sans aucun problème. Nous pourrons ainsi profiter du modèle objet proposé par cette bibliothèque afin de binder les différentes propriétés des photos telles que le titre, la description, les différentes miniatures, etc.
Afin de permettre au développeur de mettre en place une pagination en quelques lignes de code, nous allons rajouter deux propriétés au contrôles : la propriété PageIndex afin de définir l'index de la page à afficher et la propriété PageSize afin d'indiquer le nombre d'éléments dans chaque page.
Afin de bien gérer les différents cycles de postback pouvant intervenir, nous allons stocker ces propriétés dans le ViewState :

public int PageSize

        {

            get 

            {

 

                if (ViewState["flickrPageSize"] != null)

                    return (int)ViewState["flickrPageSize"];

                else

                    return 0;

            }

            set 

            {

                ViewState["flickrPageSize"] = value;

            }

        }

 

        public int PageIndex

        {

            get 

            {

                if (ViewState["flickrPageIndex"] != null)

                    return (int)ViewState["flickrPageIndex"];

                else

                    return 0;

            }

            set 

            {

                ViewState["flickrPageIndex"] = value;

            }

        }

Il est maintenant nécessaire de modifier la méthode GetSetPhotos afin de prendre en compte ces propriétés et modifier l'affichage en fonction de leur valeur.

public void GetSetPhotos()

        {

            m_flickr = new Flickr(m_apiKey);

            Photoset set = m_flickr.PhotosetsGetPhotos(ViewState["flickrPhotoSetId"].ToString());

            Photo[] setPhotos;

            if (PageSize == 0)

            {

                m_photos = set.PhotoCollection;

                return;

            }

            if (PageSize * PageIndex > set.PhotoCollection.Length || PageIndex<0)

            {

                setPhotos = new Photo[0];

            }

            else

            {

                if (PageIndex * PageSize + PageSize > set.PhotoCollection.Length)

                {

                    setPhotos= new Photo[PageSize-((PageIndex * PageSize + PageSize)-set.PhotoCollection.Length)];

                }

                else 

                setPhotos = new Photo[PageSize];

            }

 

            for (int i=0;i<setPhotos.Length;i++)

            {

                setPhotos[i] = set.PhotoCollection[PageSize * PageIndex + i];

            }

            m_photos = setPhotos;

 

        }

 
» Démarrer une discussion