Archive

Archives pour la catégorie ‘.Net’

Silverlight Analytics Framework

 

Faire une application Silverlight c’est bien.

L’exposer sur le web, c’est mieux.

Avoir des utilisateurs c’est top.

…Mais combien d’utilisateur j’ai ? Et que font-ils sur mon application ?

Genre la feature de la mort qui tue que j’ai mis 2 semaines à dev est-elle utilisée ?

Appart aller faire du porte à porte auprès de vos utilisateurs, ce genre d’informations n’est pas facile à obtenir (quoique le porte à porte ne l’est pas non plus)

Bien sûr il est possible d’envisager de se recoder une petite librairie qui va loguer l’ensemble des actions de vos visiteurs et ensuite passer encore des jours entiers à vous faire un panel pour voir l’ensemble de ces informations de façon pratique.

Ou bien…il vous suffit d’utiliser Silverlight Analytics Framework qui fait le café pour vous.

Ce Framework est juste bien fait :) .

Son nom devrait je trouve évoluer car même si au départ penser pour du Silverlight, il est maintenant compatible avec l’ensemble des technologies WP/E (WPF, Silverlight, WP7).

Son but est d’offrir de manière très simple une manière de logguer les actions des utilisateurs sur nos applications et au lieu de refaire le monde, utilisez les panels qui existent déjà pour nous afficher l’ensemble des informations collectées.

Prenons un exemple concret :

Vous avez une page de votre application qui porte le doux nom de MyKillerFeature qui contient un truc qui déchire tout sur le plan technique, il serait bon de savoir si vos utilisateurs s’en servent.

Le Framework va vous permettre de savoir d’un part si vos utilisateurs cliquent sur le lien de votre page mais également le temps qu’ils passent dedans et/ou les actions qu’ils font dedans.

Et c’est là que vous allez vous rendre compte que même pas 10% vont voir et qu’en moyenne ils y restent moins de 5 secondes tellement la KillerFeature est sans intérêt pour eux, simple et pauvre user  lambda:).

Mais comment cela marche me direz-vous ?

Simplement je répondrais !

Tout ce fait dans Blend (rien ne vous empêche de loguer des choses dans le code-behind !) d’une façon vraiment simple et a la porté du premier designer venu !

Comme nous l’avons vue, la force du Framework est de se reposer sur l’existant en termes d’outil d’analyse, donc avec un peu de chance, votre favori est déjà géré par le Framework.

Une fois le Framework installé, ouvrez votre page xaml puis glisser le behavior d’analyse qui vous convient sur le layout principal, pour ma part je vais prendre googleAnalytics et le configurer avec le code UA obtenu sur mon compte Google.com/analytics.

La marche à suivre étant la même avec les autres outils d’analyse, il vous suffit de rentrer votre code de tracking(ou identifiants divers).

clip_image001

clip_image002

Voilà, nous avons maintenant fait le plus dur, oui oui !

Lors de l’ouverture du menu behavior vous avez pu voir qu’il en existe beaucoup :

· Plusieurs du type *Analytics, comme nous l’avons vu ce sont nos outils d’analyse et rien ne vous empêche d’en mettre plusieurs à la fois.

· Des Track*, ce sont ces behaviors qui vous permettent…et bien de tracker les actions utilisateurs.

Prenez un exemple simple, glissez un TrackAction vers vos boutons de menu, vérifiez que leur events sont bien réglés sur « Click » et…et bien c’est tout.

Au runtime, les behaviors vont « communiquer » ensemble pour transmettre les informations vers votre interface d’analyse, dans mon cas Google analytics.

A noter que lors de la collection des events, chaque Track* remonte le nom du contrôle auquel le behavior est attaché, il est donc judicieux de donner des noms « propres » a ses contrôles ;) .

Je ne vais pas répéter longuement la doc en vous listant l’ensemble des behaviors disponible mais en bref :

-actions de type event classique

-action de navigation

-action de formulaire (quelles sont le top5 des recherches faites ?)

-action de type Media (combien de temps l’user moyen regarde ma vidéo avant de la stopper ?, est-il passé en fullscreen ?)

-bien d’autre (et rien ne vous empêche bien sûr d’ajouter les vôtres au besoin.

Voilà un Framework qu’il est bon et pratique :) .

Qui plus est, bien fait, on y retrouve des fonctionnalités agréable telles que :

· Gestion des applications Out of Browser

· Gestion du mode offline (envois des stats une fois online)

· Gestion totalement par behavior, ne réclame aucune ligne de code

· Gestion du A/B Testing (offrir une interface particulière (VisualState powered) à 10% de ses users et voir leurs réactions)

Et une liste d’outils d’analyse qui s’agrandit encore régulièrement :

clip_image004

La liste ne vous convient pas ? Votre outil n’est pas dessus ?

Un behavior vous permet d’indiquer un endpoint « home-made » pour les datas donc ajouter votre panel d’analyse perso ne devrait pas être bien long.

Et ensuite rien ne vous empêche de faire un behavior spécial pour votre panel et l’offrir (ou non) a d’autre utilisateur.

Le résultat ? Dans le cas de Google analytics, les statistiques sont disponible chaque nuit sur les coups de minuit, voici celle que j’ai récupéré pour mon petit sample :

clip_image005

clip_image007

On retrouve les catégories que j’ai indiquées dans mes behavior et la répartition du type d’action qui ont été logués.

Si on explore un peu les sous menu, on peut avoir de nombreux détails.

clip_image009

A vous d’avoir une nomination correcte pour vous y retrouver.

Voilà, je pense que nous avons fait un tour rapide de qu’est-ce que Silverlight Analytics Framework et comment l’utiliser pour obtenir un maximum d’information sur ses utilisateurs.

Mettre en place une solution de surveillance sur ses sites est devenu une habitude/obligation depuis quelques années maintenant mais ce n’est pas encore un réflexe au niveau applicatif.

Pourtant nous avons beaucoup à apprendre des habitudes de nos utilisateurs :) .

Je vous invite tout de même a prévenir sur vos applications que des informations quand a son utilisation sont envoyées ;) , offrir un moyen d’activer ou non cette option est également des plus conseillé pour éviter tout ennuis.

L’activation ou non peut ce faire simplement avec quelques lignes de code.

Categories: .Net, Blend, Silverlight, WPF Tags: , , ,

Visual Studio LightSwitch

vs_lightswitch_beta_logo

Ou comment créer une application pour manipuler ses datas en quelques clics.

Car oui c’est le but, en soit rien de très nouveau mais pour une fois le produit semble vraiment prometteur et complet.

Loin d’etre une solution parfaite pour tous les cas mais cela peut depanner ;)

J’ai un profil dev donc par principe j’aurais tendance à penser que ce type de logiciel va finir par nous mettre sur la paille mais au final, pas si sûr.

En quelques mots, LightSwitch est un designer d’application, qui va en 2/3 clics permettre d’obtenir un client lourd et/ou léger pour manipuler ses bases de données, ou…toutes sorte de données.

Aucunes connaissances techniques n’est requis pour l’utiliser, il fonctionne comme un stand-alone a Visual Studio 2010 mais s’y couple parfaitement si vous avez déjà VS sur votre poste.

Et pour l’avoir essayé, je ne peux qu’affirmer que cela fonctionne vraiment bien.

Pour un projet sur lequel nous bossons actuellement au sein des laboratoires de jeux vidéo et Microsoft d’Epitech, nous avions besoin d’un panel administrateur rapidement.

LS a répondu à notre besoin en quelques minutes.

Et vu nos délais sur ce projet, les heures…journées gagnées seront plus qu’utiles sur le projet!

Et hop, une interface d’admin de nos db sur Azure de faite!

Lors de la création d’un projet LS, il vous est possible de choisir C# ou VB, pourquoi donc si tout ce fait au clic ?

Car à l’inverse de beaucoup de générateur d’interface admin (ou autre), LS n’est qu’un type de projet .Net parmi tant d’autre.

Apres après poser de solides bases avec l’éditeur, rien ne vous empêche d’ouvrir le projet comme un projet C# (ou VB) et de le personnaliser un maximum par l’ajout de fonctionnalités spécifiques à votre projet par exemple.

Voici quelques screen pour vous montrer un processus de création, a noter que j’ai pressé F5 après le cinquieme screen seulement.

1. création du projet

1

2. création d’une db ou récupération d’une existante

2

3. on choisi les tables que l’on veut gérer

3

4. il nous reste plus qu’a ajouter des “screen”, chacun etant relié a une source de Data5

5. on arrange un peu notre Screen si le besoin ce fait sentir

6

6. on lance notre programme et voila!

7

Après cette première étape, il vous est possible de choisir si vous souhaiter un mode d’authentification, une application Desktop ou Web, …, …

La rapidité de création est vraiment agréable et surtout, pour une fois on obtient quelque chose de cohérent et modifiable.

Un non informaticien est capable de faire son interface lui-même et ensuite si il désire rendre le panel un peu plus “maison” pour des besoins précis, c’est là que nous les dev on entre en jeu.

Il nous suffit de récupérer le projet, l’ouvrir comme un projet .Net classique et mettre les mains dans le code comme on adore le faireclip_image001.

Ah dernier point, pour ceux n’ayant pas de compte MSDN, une beta public est prévu a la fin du mois clip_image001[1].

http://www.microsoft.com/visualstudio/en-us/lightswitch

Categories: .Net, Microsoft Tags: ,

WP7 Push Notifications

logo-windows-phoneWindows Phone 7 approche doucement mais surement et ces derniers jours nous avons eu le droit de toucher à la version beta du SDK.

Depuis l’annonce, je suis de plus ou moins près ce nouveau OS mobile et j’en suis plutôt content dans l’ensemble, certaines limitations techniques me laisse un peu perplexe en ma qualité de dev malheureusement…

Les vidéos des devices sont sympas et…la réalité l’est tout autant ;) donc je voulais m’y intéresser d’un peu plus près après les classiques petites applications de rss reader et autre meteo reader, j’ai voulu regarder le système de notifications.

Ces notifications permettent de s’abonner à un channel de diffusion et ensuite d’être informé par le biais d’event un peu près n’importe quand (et donc même quand l’application “dort” en background).

Bon le concept…rien de bien nouveau et de magique mais comme d’habitude, le SDK est vraiment bien fait et assez souple pour permettre une intégration rapide et surtout facile au sein de nos applications mais egalement de n’importe quelles applications client/desktop/serveur.

Je ne vais pas m’étendre sur la création d’appli simple sur WP7, il commence a y en avoir un peu partout sur le net mais plus vous montrer comment en quelques lignes, on peut recevoir des notifications sur son application.

Nous allons découper cela en deux étapes, la première sera bien entendu de préparer son application à recevoir des notifications et réagir en conséquence.

La seconde sera la mise en place d’une plateforme d’envois, cela peut-être un peu près n’importe quoi…ah non enfaite n’importe quoi capable d’envoyer une requête HTTP (oui autant faire simple).

Comme évoqué, nous devons passer par un channel, il suffit d’imaginer cela comme un tuyau ou des messages peuvent se mettre en attente d’être consommé par l’application.

public HttpNotificationChannel myChannel;

A savoir que le channel pour une application peut changer entre chaque lancement mais pas obligatoirement donc il faut prendre en compte ce cas:

myChannel = HttpNotificationChannel.Find("MyChan"); //ou MyChan est un nom permettant de le retrouver par la suite a coup de ce .Find

Les deux cas:

1. Le channel existe déjà, il nous suffit de nous y abonner (if myChannel != null)

2. Le channel n’existe pas et/ou plus, on va donc l’ouvrir puis s’y abonner

Pour ouvrir notre channel, deux instructions:

myChannel = new HttpNotificationChannel("MyChan");
myChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(myChannel_ChannelUriUpdated);
myChannel.Open();

Bon d’accord…trois instructions car l’event ChannelUriUpdated est là pour nous informer que l’adresse de notre channel, assez pratique pour la communiquer aux autres (les “senders”).

En version simple, voici la méthode en question:

void myChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
    Debug.WriteLine("Notification channel URI:" + e.ChannelUri.ToString());
}

La, bien sûr il faut imaginer implémenter l’envoi de cette uri vers un server ou un autre client pour qu’ils sachent par ou envoyer les notifications.

Je vous laisse mettre en place cette partie, en fonction de vos besoins.

Il existe trois types de notifications possibles, chacune ayant un rôle particulier et un “champs d’action”

1. Les Raw notifications, système le plus “ouvert” car permettant d’envoyer un peu près ce que l’on veut, c’est donc la façon pour communiquer avec son application tout ce qui concerne la logique de l’application.

2. Les Tile notifications, sont celle pour mettre à jour la tile de l’application si celle-ci est “pin to start” (comprendre par la, mise en avant sur la page d’accueil du téléphone), on peut faire varier l’image mais également un compteur (prenons exemple du nombre de mail non lu) et le titre de la tile

3. Les Toast notifications, elles permettent d’afficher un petit bandeau en haut de l’écran qui contient l’icône de l’application, un titre et un sous-titre. Utile pour par exemple informer qu’une chose est arrivée dans l’application et si on clique dessus, l’application s’ouvre.

Voici une illustrations pour les Tile et une pour les Toasts, les autres n’ayant pas de visuel ( sauf si choix du développeur)

Un exemple de tile:

wp7Tile3

Un exemple de Toast:

wp7Toast

Ensuite il suffit de brancher notre channel au shell du telephone, pour cela:

myChannel.BindToShellTile(); //pour s’abonner aux Tiles

Suffit pour cela.

Nous allons pour le reste ajouter le bind des toasts:

myChannel.BindToShellToast(); //pour s’abonner aux Toasts
/* pour recevoir les Raw */
myChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(myChannel_HttpNotificationReceived);
/* gestion des erreurs */
myChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(myChannel_ErrorOccurred);

Et un event nous permettant de gérer les erreurs.

Celui du milieu étant pour gérer les Raw :) .

Je ne vais pas m’étendre sur les raw, il faut savoir que l’on envoie un buffer dans ce type de notification donc ensuite le protocole de communication dépend entièrement de l’application cible, il faut mettre en place une API que l’envoyeur comme le destinataire connait.

Une fois l’event levé, il vous suffit de lire le contenu de e.Notification.Body pour y entrainer vos informations.

Rien de plus n’est nécessaire, nous somme déjà en mesure de recevoir tout ce qui nous intéresse!

Passons donc à l’envois de notification, on part du principe que vous avez communiqué l’adresse du channel a un serveur qui par exemple va de temps en temps envoyer une notification vers les clients abonnés.

Dans notre exemple nous simulerons cela par une adresse superbement gérer au sein d’un copier/coller car c’est bien plus classe au sein d’un tuto :) .

Etudions déjà la structure des messages à envoyer dans le cas d’un Toast ou d’un Tile, à savoir que c’est encore sujet a modification donc dans le cas d’une mise à jour, si cela ne marche plus, pas de panique, il suffit d’aller voir sur la page MSDN la nouvelle version: http://msdn.microsoft.com/en-us/library/ff402545%28v=VS.92%29.aspx

Dans le cas d’un Tile, on va donc envoyer:

string tileMessage = String.Format("Content-Type: text/xml\r\nX-WindowsPhone-Target: token\r\n\r\n" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Tile>" +
"<wp:BackgroundImage>{0}</wp:BackgroundImage>" +
"<wp:Count>{1}</wp:Count>" +
"<wp:Title>{2}</wp:Title>" +
"</wp:Tile> " +
"</wp:Notification>", this.Image.Text, this.Count.Text, this.Message.Text);

On voit donc trois paramètres servant à:

1. Indiquez l’image à mettre en background de Tile, doit être contenu dans l’application ou à télécharger sur un serveur “autorisé” (lors du BindToShellTile, une surcharge permet de lister les serveurs “autorisés”, image qui doit prendre moins d’une minute à se télécharger!)

2. Un compteur, par exemple le nombre de mail non lu

3. Un titre, je vous laisse deviner

Et dans le cas d’un Toast:

string toastMessage = String.Format("Content-Type: text/xml\r\nX-WindowsPhone-Target: toast\r\n\r\n" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>{0}</wp:Text1>" +
"<wp:Text2>{1}</wp:Text2>" +
"</wp:Toast>" +
"</wp:Notification>", this.Message.Text, this.SubMessage.Text);

Cette fois ci, deux paramètres:

1. Un titre

2. Un sous-titre

Et là on se demande ou l’envoyer? Et bien tout simplement vers notre adresse de channel donne par l’application et que l’on va donc récupérer sur notre serveur ou…dans le buffer magique du copier/coller :D .

Pour cela, je ne vais pas m’étendre sur l’explication de ce code, rien de bien mystérieux:

HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);
sendNotificationRequest.Method = "POST";
sendNotificationRequest.Headers = new WebHeaderCollection();
sendNotificationRequest.Headers.Add("X-NotificationClass", codeHeader);
byte[] notificationMessage = Encoding.Default.GetBytes(msg);
sendNotificationRequest.ContentLength = notificationMessage.Length;
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
{
    requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
response = (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

Il nous suffit donc d’appeler ce code avec subscriptionUri correspondant a notre adresse de channel et petite astuce, codeHeader doit prendre la valeur de “1” dans le cas d’un Tile et “2” pour un Toast.

msg etant bien sur le flux xml de la notification.

Je dois admettre que cette petite différence de code header est casse pied mais la doc est très clair la dessus :) .

Dans le cas d’un envoi d’information en Raw, une fois votre protocole défini, il vous suffit d’envoyer l’information sans mettre de code header particulier.

Si on prend l’exemple MSDN :

new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

Rien de nous empêche bien sûr d’envoyer des textes en clair ou autre information, quand que les deux parties savent le lire et l’écrire correctement :) .

L’idée est de permettre un transfert simple d’information même quand l’application n’est pas active (car si active, un simple webservice suffit amplement).

Pour les toast, je vous laisse vous reporter a l’image plus haut pour voir a quoi cela ressemble, concernant le changement de tile et l’ajout d’information, voici une illustration:

wp7Tile2

Je n’ai mis que de petit bout de code pour me concentrer sur l’essentiel mais pour ceux n’ayant pas réussi à remettre cela en ordre, voici une classe complète permettant de gérer les abonnements.

public class Notification
{
    public HttpNotificationChannel myChannel;
    public void CreatingANotificationChannel()
    {
        myChannel = HttpNotificationChannel.Find("MyChan");

        if (myChannel == null)
        {
            myChannel = new HttpNotificationChannel("MyChan");
            myChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(myChannel_ChannelUriUpdated);
            myChannel.Open();
        }
        else
        {
            Debug.WriteLine("Notification channel URI:" + myChannel.ChannelUri.ToString());
        }
        myChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(myChannel_HttpNotificationReceived);
        myChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(myChannel_ErrorOccurred);
        myChannel.BindToShellTile();
        myChannel.BindToShellToast();
    }

    void myChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
    {
        Debug.WriteLine("Notification channel URI:" + e.ChannelUri.ToString());
    }

    void myChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
    {
        switch (e.ErrorType)
        {
            case ChannelErrorType.ChannelOpenFailed:
                // ...
                break;
            case ChannelErrorType.MessageBadContent:
                // ...
                break;
            case ChannelErrorType.NotificationRateTooHigh:
                // ...
                break;
            case ChannelErrorType.PayloadFormatError:
                // ...
                break;
            case ChannelErrorType.PowerLevelChanged:
                // ...
                break;
        }
    }
    void myChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
    {
        if (e.Notification.Body != null && e.Notification.Headers != null)
        {
            System.IO.StreamReader reader = new System.IO.StreamReader(e.Notification.Body);
        }
    }
}

J’ai également mis en place une page web vous permettant d’envoyer des notifications sur un channel que vous lui donnez en paramètre :) .

http://wp7.fr/push/

Categories: .Net, C#, WP7 Tags: , , ,

Un ViewModel mais plusieurs View? merci ObjectDataProvider!

La problématique est toute simple, au sein d’un logiciel, j’ai plusieurs “toolsbox” me servant à modifier mes paramètres, chaque box peut apparaitre X fois sur Y inspecteurs différents mais au final tous sont reliées au même modèles.

Face au fait que beaucoup de données sont traitées, même si toutes viennent du même modèle et donc “n’existe” qu’une fois, il n’en reste pas moins que chaque instanciation de mes ViewModel implique de jouer son rôle de proxy pour ces données, mais pas une fois, plusieurs fois pour offrir les mêmes données?!

Donc oui le pattern MVVM indique que comme on tape sur le même model, chaque viewModel offre ce qu’il faut à sa vue et puis basta, et bien dans mon cas cela ne me suffit pas.

Deux solutions sont dont offertes:

  • Instancier mon unique DataContext en codebehind lors de la création de mes vues
  • Trouver un moyen pour que la view s’occupe elle-même de récupérer une instance unique de son ModelView

Ayant pris l’habitude d’utiliser blend, car blend c’est vraiment la vie (une petite pensée pour Dick Lantim qui aura essayé pendant deux mois de me convertir sans réussir…je regrette de ne pas avoir été un bon élève!), j’ai donc opté pour la seconde solution.

L’idée est de remplacer le code suivant qui permet l’instanciation du DataContext par un autre permettant de juste récupérer une instance unique du DataContext.

<UserControl.DataContext>
        <ModelView:BoxCamera/>
</UserControl.DataContext>

L’idée va être de passer par un ObjectDataProvider que nous allons déclarer une fois pour toute dans le App.xaml:

<Application.Resources>
    <ObjectDataProvider MethodName="GetInstance" ObjectType="{x:Type ModelView:BoxCamera}" x:Key="BoxCamera"/>
</Application.Resources>

Et notre ModelView va maintenant passer en mode Singleton pour renvoyer une unique instance qui va donc nous permettre de soulager un peu l’application en évitant de créer plusieurs ModelView quand un seul est nécessaire.

private static BoxCamera _instance;
        public static BoxCamera GetInstance()
        {
            if (_instance != null) return _instance;
            else
            {
                _instance = new BoxCamera();
                return _instance;
            }
        }
private BoxCamera() {}

Il nous reste plus qu’à faire notre binding de DataContext dans notre View et ensuite son utilisation est totalement transparente:

DataContext="{DynamicResource BoxCamera}"

Et voilà, plusieurs vue, un seul DataContext instancié donc dans certains cas le gain est vraiment appréciable :) .

Ce cas est assez particulier car repose sur un besoin que je viens d’avoir mais il faut noter que l’ObjectDataProvider  est vraiment pratique pour gérer un peu plus finement les créations de DataContext au sein de nos vues.

Par exemple, nous pouvons instancié un ModelView précis:

<ObjectDataProvider  ObjectType="{x:Type ModelView:BoxCamera}" x:Key="BoxCamera"/>

Mais dans le cas où nous aimerions passer des paramètres a notre constructor?

<ObjectDataProvider MethodName="GetInstance" ObjectType="{x:Type ModelView:BoxCamera}" x:Key="BoxCamera">
    <ObjectDataProvider.ConstructorParameters>
        <system:String>Stumpy</sys:system>
    </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

Vous avez besoin d’une donnée précise dans un morceau de votre application mais bon, pour X raison le ViewModel de cette vue ne contient pas la donnée et son ajout est peu pratique/élégant?
Aucun soucis car il vous suffit de récupérer notre ressource déclarée plus haut comme source et vous binder dessus:

<TextBlock Text="{Binding Path=FocaleValue, Source={StaticResource BoxCamera}}"/>

Bon il faut avouer, ce n’est pas super propre comme façon de faire mais disons que cela peut dépanner dans certains cas.

Un ViewModel un peu long à charger?
Aucun soucis, en settant IsAsynchronous a true, notre ViewModel est chargé en async donc on soulage encore un peu nos vues lors des phases de lancement.

Et nous pouvons sans doute lui trouver encore d’autres utilités :) .

Categories: .Net, Blend, C#, WPF Tags: , , , ,

OData, Comment lire un flux?

Dans l’article précèdent, nous avons mis en place un WebService offrant un accès sur une base de donnée par le biais du protocole OData.
Nous avons vu qu’il était possible de lire le flux par le biais du logiciel LinqPad mais également un simple navigateur.
Il serait intéressant maintenant de lire cela dans une application directement, non?

Je vous invite donc à reprendre votre solution de test fait dans l’article précèdent et y ajouter un projet de type WPF application.

clip_image002

Nous allons ensuite faire une petite interface qui va juste nous permettre d’avoir un rendu visuel, pour le cote sexy de l’application on repassera plus tard ;) .

clip_image003

Pour vous faire gagner un peu de temps, voici le code xaml de la fenêtre :

<Grid>
    <Button Content="Refresh" Click="Button_refresh" Margin="214,0,213,258" />
    <ListBox x:Name="myList" Margin="0,0,295,0" />
</Grid>

Nous avons donc une ListBox et un Button, il reste maintenant à offrir une source de donnée à notre superbe application.

Pour cela, on ajoute une référence vers notre WebService comme d’habitude :
Clic droit sur References dans le projet puis ajouter un « service reference »
Notre service étant dans notre solution, il vous suffit de faire « Discover » puis de lui donner un petit nom, par exemple « MyService »

clip_image001

Rien de bien nouveau en soit, voyons maintenant comment remplir notre listbox.

Notre bouton de refresh étant brancher sur un évènement clic, il nous suffit de rajouter la méthode suivante en code-behind de notre fenêtre :

private void Button_refresh(object sender, RoutedEventArgs e)
{
    this.db = new MyService.NORTHWNDEntities(new Uri("http://localhost:26162/WcfDataService1.svc"));
    var query = from c in db.Contacts select c;
    this.Contact = new DataServiceCollection<MyService.Contacts>(query);
    this.myList.ItemsSource = Contact;
}

Pensez à ajouter les propriétés de classe :

MyService.NORTHWNDEntities db = null;
DataServiceCollection<MyService.Contacts> Contact = null;

Mais aussi à remplacer le port par celui sur lequel tourne votre service !

La première ligne est là pour nous permettre de récupérer un context sur notre webService et nous allons ensuite nous en servir pour l’interroger.
Dans mon cas, je souhaite récupérer l’ensemble des contacts donc ma requête reste assez simple et je la passe ensuite dans le constructeur de ma DataServiceCollection.
Il me reste plus qu’à donner comme source à ma liste la collection en question :) .
Je vous laisse essayer et constater que « normalement » tout marche comme prévu, quoique l’affichage de notre listbox n’est pas très agréable à voir.

Un petit ajout dans le xaml semble utile, remplacer votre listbox par celui-là puis relancer

<ListBox x:Name="myList" Margin="0,0,295,0">
    <ListBox.ItemTemplate>
        <DataTemplate>
             <TextBlock Text="{Binding ContactName}" />
        </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

Déjà un bon résultat pour si peu de travail.
Une problématique qui peut se poser est la pagination des données, oui dans notre cas la liste des contacts n’est pas énorme mais dans le cas où elle contiendrait des milliers de données ?
Hmm…Un peu lourd de tout récupérer d’un coup peut-être ?

Retournons dans notre webservice et essayons de faire un système permettant de n’envoyer seulement que N éléments à la fois et s’arranger pour envoyer N de plus sur demande.
On se souvient avoir mis la ligne

config.SetEntitySetAccessRule("Contacts", EntitySetRights.All);

Ajoutons cette petite ligne à la suite :

config.SetEntitySetPageSize("Contacts", 42);

Et…voilà, notre système de pagination est fini, mon café n’a même pas eu le temps de refroidir…
Je vous laisse relancer votre client et constater que maintenant on ne récupère plus que les 42 premiers éléments de notre table, ajoutons donc un système pour récupérer la suite !

Retour dans le xaml pour y ajouter un petit bouton dont voici le xaml a glissé dans votre fenêtre :

<Button Content="Next" Click="Button_Next" Margin="314,0,112,258" />

Allons maintenant remplir le code de l’event sur lequel pointe ce bouton:

private void Button_Next(object sender, RoutedEventArgs e)
{
    if (this.Contact == null || this.Contact.Continuation == null)
        return;
    this.Contact.Load(this.db.Execute<MyService.Contacts>(this.Contact.Continuation.NextLinkUri));
}

Donc un petit check pour eviter de planter dans le cas ou notre liste n’aurait pas été chargées au préalable
Et ensuite, on charge la suite de notre collection, pour cela un petit appel à notre context en lui indiquant que l’on veut récupérer « la suite ».

Si vous regardez la valeur de NextLinkUri vous y verrez une simple uri avec un argument indiquant « quoi renvoyer »
Encore une fois, rien de bien sorcier, l’ensemble du process est géré pour nous.

Je vous laisse vous amuser avec votre nouveau bouton pour voir ce remplir votre liste de contact et de mon cote je garde encore mon café chaud pour le moment !

Jusqu’à la, nous avons fait de la lecture de base, on se souvient d’avoir laissé le service ouvert en écriture pour la table Contacts donc essayons d’y ajouter un élément ;) .
Encore une fois, voici un petit morceau de xaml à ajouter dans votre fenêtre :

<Button Content="Add" Click="Button_Add" Margin="419,0,12,258" />

Et voici le code allant avec notre event d’ajout:

private void Button_Add(object sender, RoutedEventArgs e)
{
    if (this.Contact == null)
        return;
    this.Contact.Add(new MyService.Contacts()
    {
        CompanyName = "42",
        ContactName = "Marvin"
    });
    db.SaveChanges();
}

Un petit check pour la forme puis on ajoute un contact dans notre collection.
Et puis on demande au context de nous sauvegarder les changements.

Voilà, notre mini gestionnaire de contact est terminé, je vous laisse le décorer pendant que je déguste mon café.

La version en Silverlight reposerait sur le même code, juste noter que l’ensemble des appels au webservice seraient asynchrones comme toujours en Silverlight

Categories: .Net, C# Tags: , , , ,

OData, ou comment offrir de l’information facilement

La mise en route d’un web service reposant sur Odata n’a rien de bien compliqué, on va dire qu’elle est même très facile :) .

A savoir qu’il n’est qu’une évolution ou plutôt une standardisation pour essayer de rendre uniforme l’ensemble des distributeurs de données sur internet.

De nombreux services de Microsoft reposent maintenant dessus.

Son application de la licence Open Specification Promise et la mise à disposition de nombreux SDK pour un peu près toutes les plateformes a pour but de mieux promouvoir son adoption.

Il me suffit de me souvenir d’un de mes stages ou je bossais avec pas mal avec des sources de données diverses et à chaque fois c’était la même histoire : « Alors celui-là…je le formate comment ? Ah et celui-là je dois l’envoyer sous quelle forme ? ».
Bref, pas mal de temps perdu et en plus source d’erreur.

on peut le voir donc comme une protocole commun d’échange de data, une sorte d’API générique de communication et franchement qui pourraient s’en plaindre?
Dans notre exemple nous allons prendre comme source une base de donnée mais rien ne nous empêche d’offrir d’autres données venant du filesystem, d’autre flux que nous rassemblons, de twitter?

Ce type de service n’est pas là pour offrir de la logique, son nom est assez clair je pense ;)
Comprendre par là qu’Odata est là pour offrir des informations, on peut y appliquer un certain niveau de contrôle mais cela repose surtout de la gestion d’autorisation. Mais tout reste bien sur possible…

Voici la marche à suivre pour mettre en route un « producer Odata » :

1. Créer un nouveau projet dans Visual Studio 2010, de type WCF et supprimer le Service1 créé car nous allons le remplacer.clip_image002[4]

2. Ajouter votre base de donnée, pour faire original nous allons prendre Northwind

step2

3. Ensuite nous allons mapper la base par le biais d’EntityFramework donc ajoutez un item de type « ADO.NET Entity Data Model » et on le laisse faire son travail sur notre base.clip_image005[4]

4. Vient maintenant l’étape de mise en route du Service, on ajoute donc un item de type « WCF Data Service » que nous allons appeler « MyService ». Le fichier généré contient pas mal de commentaire que nous allons « retravailler » pour configurer notre service.clip_image007[4]

Voici la version permettant de faire tourner notre service, vous remarquez que nous avons même « gagné » en nombre de ligne ;) :clip_image009[4]

Et c’est fini, oui quatre petites étapes pour mettre en mettre à disposition vos données qui pourront être requêtées par le biais de client multiple, .Net desktop, .Net web, .Net mobile mais aussi PHP, java, objective-c, …

Pour vos tests, je vous conseil fortement d’ajouter le fichier ClientAccessPolicy.xml a la racine de votre projet et d’y mettre le contenu suivant :

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

Cela permettra à des clients qui sont dans un autre domaine que votre service de pouvoir l’utiliser car par défaut ce comportement est interdit.

Si on remonte un peu plus haut, on remarque que notre service est configuré pour mettre la lecture de l’ensemble de nos tables mais est-ce vraiment un choix judicieux ?

Il vous suffit d’affiner un peu les droits en indiquant en paramètre le nom d’une table et ensuite de lui setter une valeur qui vous convient, on peut imaginer par exemple :

config.SetEntitySetAccessRule("Contacts";, EntitySetRights.All);
config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead);

Pour mettre à disposition seulement les tables Contacts et Customers mais a noter que Contacts sera également en écriture.

Oui le protocole permet bien sur la mise à disposition d’information mais également leurs éditions, encore heureux !

Pour avoir un premier aperçu, je vous conseil l’utilisation d’un logiciel tel que LinqPad pour explorer votre service, la version Beta tourne maintenant avec .Net4 donc aucun souci pour notre service: http://www.linqpad.net/Beta.aspx
A noter qu’un simple navigateur vous suffit, l’ensemble reposant sur des protocoles bien connu : http://localhost:*****/WcfDataService1.svc/Contacts (remplacez les étoiles par le numéro de port qu’utilise votre serveur de test).
Oui, OData n’est qu’une surcouche et ensemble d’outils pour faciliter la vie et on va pas s’en plaindre :) .

Prochaine article, nous verrons comment utiliser les informations au sein d’un client, reposant sur une techno .Net ou non (mince…je vais devoir me farcir du php?!).

Et ensuite, nous verrons comment gérer plus en profondeur les options d’Odata.

Par exemple permettre l’écriture seulement à certains utilisateurs ?

Categories: .Net, C# Tags: , ,

Envie d’essayer Windows Server 2008 R2?

1256130227_windows-2008-r2-logo1

Les échos à propos de cette nouvelle monture de l’OS serveur de Microsoft sont plutôt bon que ce soit sur le plan architecture mais surtout perf (le gros point noir de Windows serveur mais qui tend à disparaitre à chaque nouvelle version).

Pour constater cela par vous-même, il existe plusieurs moyens:

  • Monter un petit serveur à la maison mais peu pratique pour la mise sur internet
  • Prendre un hébergement dans un date-center mais un peu cher pour le Test.

Ou alors, profiter de l’offre que s’apprête à lancer Microsoft!

A partir de la semaine prochaine, 5000 serveurs seront disponible gratuitement sur simple inscription et cela jusqu’à fin juin.

Une fois votre machine attribuée, vous pourrez vous y connecter en rdesktop comme sur un vrai serveur dédié (une vm mais c’est transparent de nos jours) et vous amuser sur trois grands axes:

1. L’administration d’un Windows server, découvrir ou tester les nouveautés

2. L’hébergement de site, application et autres services

3. Le travail collaboratif avec la mise en service (automatique!) d’un serveur TFS! (mise en route vers le 8 mars)

Une fois l’offre finie (et oui, toute les bonnes choses ont une fin), il sera possible de récupérer votre VM pour la redéployer ou même la migrer sur une plateforme d’hébergement “classique” et donc cette fois payante (et oui, il faut bien payer le Datacenter un jour ;) ).

180x150_MaPlateformeWeb_v2_021210

Microsoft lance une opération de mise en avant de sa plateforme web : 5000 serveurs tout équipés gratuits jusqu’au 30 juin pour mener à bien vos projets web ! Une occasion à ne pas manquer : même ceux qui ne connaissent pas l’environnement Windows pourront le prendre en main rapidement avec des pas à pas dédiés autour des scenarii clé tels qu’apprendre à gérer un serveur web ou créer un site web avec Joomla, DotnetNuke, Drupal ou WordPress… et plus à venir dans les prochaines semaines !

On peut donc résumé en quelques mots:

Envie d’avoir un serveur dédié rien qu’à vous durant plusieurs mois pour découvrir, tester, apprendre, s’amuser et même…oui même travailler!

Microsoft vous offre cette possibilité et il vous suffit de vous rendre à cette adresse:

maplateformeweb.com

[Série]Exploration de .Net – Début de l’expédition.

07/11/2009 Stumpy 5 commentaires

Plus j’avance dans l’apprentissage des technologies .Net, plus je ressens le besoin de mieux comprendre comment cela marche « à la base ». Cela tiens sans doute de mon cursus qui m’a toujours poussé à connaitre ce que j’utilise pour en tirer le meilleur.

.Net, maintenant tout le monde connait à peu près (du moins toute personne touchant un peu à l’informatique) et pour faire un bref résumé « c’est comme java mais en mieux/moins bien ».

On peut donc comprendre que .Net est une technologie reposant sur une exécution des programmes écrits par le biais d’une machine virtuelle, on n’est pas trop loin de la réalité.

.Net, c’est un vaste univers mais l’idée globale reste que chaque langage qualifiable de .Net respecte certains principes et partage certaines informations permettant d’être compatible.

Pour cela, lors de la compilation d’un code, on passe par une étape, une sorte de traduction dans un langage commun, le MSIL pour Microsoft Intermediate Language (IL dans un contexte général, par exemple dans son implémentation avec mono).

Cette étape permet donc de rendre compatible tout langage reposant sur .Net, le passage de C#, VB.net et autre est facile et aisé, la transformation dans l’autre sens l’est tout autant mais surtout sans restriction quand au besoin de revenir au langage source!

Avant de se lancer dans la partie « pratique », il nous reste à conclure le processus en indiquant que ce langage commun, une fois passé sous son format binaire (Donc on note qu’il est tout a fait lisible en temps normal !), est « le binaire » fournis à l’utilisateur. Lors de l’executation la CLR (Common Language Runtime) se charge de transposer les instructions dans quelque chose de compréhensible par la machine hôte et…voila !

Partons du principe que vous savez déjà développé un minimum, si possible avec un langage .Net.

Comme tout début dans un langage et par tradition datant des temps obscurs de l’humanité, un « hello world » est une obligation donc listons les outils nécessaires pour ce petit travail. A savoir que si vous avez déjà un visual studio d’installé, il est fort probable que tout soit déjà près, assez logique il est vrai.

· Ilasm, fournis dans le SDK de .Net

· Ildasm, de même

· Notepad (notepad++ si on veut « bien » faire les choses mais en rien une obligation)

Pour des raisons pratiques de PATH système, utilisez votre menu démarrer pour lancer un prompt intégrant les PATH visual studio, vous pourrez le trouver dans le dossier tools de visual studio.

Ecrire un programme directement dans cet Intermediate Language est tout à fait possible et nous allons le prouver très facilement. Ouvrez un fichier que l’on nommera main.il et copier/coller le code suivant :

.assembly extern mscorlib {} // link un assembly extern

.assembly Hello {}            // defini tl'assembly

.method public static void Main() //declare la method Main

{

.entrypoint //point d'entrée de l’assembly

.maxstack 1 //taille max de la stack pour cette méthode

ldstr "Hello, world!" //charge la string sur la stack

call void [mscorlib]System.Console::WriteLine(string) // appel la méthode

//WriteLine avec une string

ret  //fin de la méthode

}

Je pense que l’ensemble des commentaires parle d’eux même pour vous permettre de comprendre ces quelques lignes, l’ensemble partage un peu de la syntaxe de l’asm et un peu du C, avec un petit touche d’objet, formule intéressante et qui a le mérite d’être complète.

Pour ceux se demandant ce qu’est cette fameuse stack, pour le moment imaginez cela comme une zone mémoire ou l’on peut stocker n élément, dans le cas présent on déclare une zone pouvant en contenir maximum un à la fois.

On remarque l’absence de toute classe, mais nous verrons rapidement qu’il est tout à fait possible d’utiliser classe, interface et tous les « classiques » de la programmation objets.

Dans le prompt, rendez vous dans le dossier contenant votre fichier .il puis « compilez » avec:

Ilasm main.il

Vous pourrez recueillir certaines informations mais surtout la fin vous indiquant que l’ensemble a correctement été compilé et un fichier hello.exe est maintenant dans le dossier.

image

Je vous laisse le lancer et voir hello world s’afficher dans la console.

Remontez un peu dans votre console et ajoutez un petit ‘d’ puis modifiez l’extension du fichier pour obtenir :

Ildasm main.exe

Ildasm permet de désassembler un binaire .Net pour retrouver son code IL, vous pourrez facilement retrouver votre code mais également quelques informations supplémentaire que nous détaillerons dans l’épisode 2 de cette série.

image

Voila pour le premier épisode, l’objectif n’était pas de rentrer dans le détail mais plutôt de survoler l’ensemble pour vous donner gout à chercher un peu plus loin mais surtout savoir ce qu’il ce passe lors d’une compilation en .Net.

Dans la suite de cette série, nous avanceront ensemble pour tenter de mieux comprendre les fondations de la technologie .Net, toujours dans le but de mieux connaitre ses outils.

Qu’est-ce que sont les metadata? Découvrir plus d’instruction permettant de « remplir la stack », la manipuler, la notion d’objet mais aussi appliquer des branchements logiques dans le code,…,… tout cela dans les prochains épisodes !

Categories: .Net, C# Tags: ,