Tutorial Silverlight 4 WCF RIA Services avec quelques lignes de code – Partie 3

Article mis à jour : mai 2010 pour la sortie de Silverlight 4 RTW et WCF RIA Services RTW

Je vous ai montré dans ce 2ème billet comment ajouter de la pagination, une animation d’attente (BusyIndicator) et une vue maître/détail. Le thème de cette 3ème partie sera de voir comment changer le look & feel de notre application, les principes de base de l’authentification avec RIA Services, comment enregistrer les modifications effectuées dans le client Silverlight vers le serveur et pour finir comment gérer un minimum de sécurité dans son application RIA en fonction du niveau d’authentification.

Reprenez le projet que vous avez réalisé à l’étape précédente. Sinon, vous pouvez le récupérer directement ici :

1 – Lancez Visual Studio 2010 et ouvrez la solution DemoKeynoteTechdays.sln construite à l’étape précédente et positionnez-vous sur le projet Silverlight. On va commencer par un truc sympa: on va voir comment facilement changer le look & feel de notre application même pour nous les développeurs qui faisons des trucs moches (en tout cas moi ;-)).

Note : vous pouvez donc zapper cette étape du tutorial si vous le souhaitez. Cela n’aura pas d’incidence sur la suite.

Si vous vous rendez dans le répertoire “Assets” du projet Silverlight, vous observerez 2 choses intéressantes :

A - le fichier “Styles.xaml” est un dictionnaire de ressources dans lequel nous avons externalisé tout le look & feel d’une application de type “Business Application” (cela fonctionne de la même manière avec une “Navigation Application”). On va donc retrouver dedans la couleur d’un onglet sélectionné, sa forme, etc. L’avantage de l’avoir externalisé est que l’on va pouvoir facilement le faire changer par un designer dont c’est le métier sans que cela est d’impact sur le reste de notre application/code.

B - un répertoire “Resources” contenant par défaut 2 fichiers “ApplicationString.resx” et “SecurityQuestions.resx” contenant la valeur de certaines chaînes de caractères utilisées dans l’application (nom de l’application, message de bienvenu, etc.). Une bonne pratique dont vous devriez vous inspirer dans vos propres applications !

Commençons par changer le look de notre application. Vous pouvez télécharger d’autres modèles de thèmes pour vos applications Silverlight Business/Navigation Application ici : https://gallery.expression.microsoft.com dans la partie “Themes” notamment. Ces thèmes ont été réalisés par Corrina Black : https://blogs.msdn.com/corrinab

Récupérez par exemple le thème Skyline : https://gallery.expression.microsoft.com/en-us/skylineria . Décompressez l’archive ZIP et drag’n’droppez le fichier “Styles.xaml” dans le répertoire “Assets” de votre solution Visual Studio de manière à écraser celui d’origine.

Relancez l’application. Votre application a bien changé de look sans que vous n’ayez rien à faire !

DemoKeynote_part3_001

Par contre, ces thèmes n’ont pas été mis à jour pour l’instant pour WCF RIA Services/Silverlight 4. Donc, il y a quelques soucis avec la partie “login” de notre projet. Pas d’inquiétude, on va résoudre cela dans peu de temps.

Rendez-vous maintenant dans le fichier de ressources “ApplicationString.resx” où vous pouvez localiser un minimum les messages.

DemoKeynote_part3_002

Pour vous faciliter la vie, vous trouverez le “Styles.xaml” pour le thème Skyline fixé par mes soins pour WCF RIA Services/SL4 ainsi que le fichier de ressources partiellement traduit pour vous ici :

Récupérez l’ensemble et écrasez les 2 fichiers dans votre solution avec ceux-ci. Attention : cela ne fonctionne bien que si vous avez nommez votre projet DemoKeynoteTechdays comme demandé au 1er tutorial, à cause (entre autres) de la ligne suivante dans “Styles.xaml” :

 xmlns:loginWindow="clr-namespace:DemoKeynoteTechdays.LoginUI"

Sinon, vous n’aurez que cette ligne à changer en fonction du nom de votre projet. Voici la nouvelle tête de notre application :

DemoKeynote_part3_011

2 – Regardons maintenant comment fonctionne l’authentification. Cliquez sur le bouton de connexion et vous aurez cette fenêtre (Child Window) d’affichée :

DemoKeynote_part3_003

Remplissez tous les champs :

DemoKeynote_part3_004

Une fois enregistré et connecté, vous verrez apparaître cela en haut à droite de l’application :

DemoKeynote_part3_005

Alors comment tout cela fonctionne-t-il ? Le template de projet “Business Application” repose par défaut sur les Membership Provider d’ASP.NET. Or celui-ci créé également par défaut les rôles et utilisateurs dans une base de données nommée ASPNETDB gérée par SQL Express.

Ainsi, une fois au moins 1 utilisateur de créé, rendez-vous dans le projet serveur et demandez à afficher les fichiers cachés (avec l’icône “Show All Files”). Vous verrez alors apparaître sous "App_Data”, le fichier “ASPNETDB.MDF” :

DemoKeynote_part3_006

Si vous double-cliquez dessus, vous pourrez alors explorer la base de données associée et retrouverez par exemple la table des utilisateurs :

DemoKeynote_part3_007

Mais comme on utilise les providers classiques d’ASP.NET, on peut également tout simplement faire appel au portail de configuration “ASP.NET Configuration” pour gérer les utilisateurs, les rôles, etc. Pour cela, une fois le projet serveur ASP.NET sélectionné dans l’explorateur de solution, soit vous cliquez sur l’icône suivante :

DemoKeynote_part3_008

soit dans le menu Project –> “ASP.NET Configuration”. Vous arriverez alors sur cette page :

DemoKeynote_part3_009

Déjà bien connue par ceux qui connaissant déjà ASP.NET. Rendez-vous dans la partie “Security” et créez un utilisateur “Administrateur”. Ensuite, créez un rôle “Admin” dans lequel vous inscrivez l’utilisateur “Administrateur”.

Si vous souhaitez en savoir davantage, il faut jouer un peu avec l’ensemble comme je vous l’ai déjà proposé avec un tutorial précédent où l’on personnalisait les écrans d’authentification en ajoutant une image (avatar) dans le profile de l’utilisateur.

Par ailleurs, si l’on souhaite brancher les providers sur autre chose c’est tout à faire possible. Par exemple, je l’avais branché sur le storage d’Azure en lieu et place de SQL Serveur dans Cloudy Pizza comme expliqué ici. La configuration des providers se passe dans le fichier web.config.

Si vous souhaitez par exemple connecter les providers à une base SQL 2008 (non express) distante, vous pouvez suivre cette solution : https://forums.silverlight.net/forums/t/151945.aspx

Si vous souhaitez utiliser l’authentification intégrée Windows au lieu de l’authentification par formulaire proposée par défaut, rendez-vous aussi dans le web.config et changez cette ligne :

 <authentication mode="Forms">

Par celle-ci :

 <authentication mode="Windows">

Ainsi, lorsque vous relancerez l’application, vous serez automatiquement authentifié avec la session Windows active (EUROPE\davrous ici) :

DemoKeynote_part3_010

Dans tous les cas, cela sera transparent pour le client de login de RIA Services.

Note : n’oubliez pas de repasser en authentification par formulaire pour la suite.

3 – Voyons voir maintenant comment enregistrer les modifications faîtes côté client vers notre couche d’accès aux données. Retournez sur “Home.xaml” et dans la partie en bas à droite, ajoutez un bouton (par drag’n’drop par exemple) et nommez le btnSauvegarder :

DemoKeynote_part3_012

Ensuite, double-cliquez sur le bouton pour ajouter un gestionnaire d’évènement sur le click et ajoutez y ce code :

 private void btnSauvegarder_Click(object sender, System.Windows.RoutedEventArgs e)
{
    acteursDomainDataSource.SubmitChanges();
}

1 seule ligne de code pour renvoyer l’ensemble des modifications vers le serveur. En effet, RIA Services maintient côté client un mécanisme de suivi des changements. Si vous ajoutez ainsi 2 éléments, modifiez 3 et supprimez 1, la méthode SubmitChanges() enverra ces 6 opérations vers la couche serveur pour vous.

Juste avec ce code, cela devrait fonctionner. Ajoutons tout de même un minimum de traitement d’erreurs avec le code suivant. Dans le constructeur, abonnez-vous à l’évènement de retour suivant :

 acteursDomainDataSource.SubmittedChanges += 
 new System.EventHandler<SubmittedChangesEventArgs>(acteursDomainDataSource_SubmittedChanges);

Ensuite, gérez l’évènement avec ce code:

 void acteursDomainDataSource_SubmittedChanges(object sender, SubmittedChangesEventArgs e)
{
    if (e.HasError)
    {
        System.Windows.MessageBox.Show("Erreur pendant la mise à jour !\n" + e.Error.Message);
        e.MarkErrorAsHandled();
    }
    else
    {
        if (e.ChangeSet.ModifiedEntities.Count != 0)
            System.Windows.MessageBox.Show(e.ChangeSet.ModifiedEntities.Count
                + " entitée(s) modifiée(s).");
        if (e.ChangeSet.AddedEntities.Count != 0)
            System.Windows.MessageBox.Show(e.ChangeSet.AddedEntities.Count
                + " entitée(s) ajoutée(s).");
        if (e.ChangeSet.RemovedEntities.Count != 0)
            System.Windows.MessageBox.Show(e.ChangeSet.RemovedEntities.Count
                + " entitée(s) supprimée(s).");
    }
}

Vous pouvez maintenant tester l’application en changeant par exemple le prénom de Carrie Fisher de "Carrie” à “Karrie” par exemple et vous verrez que la pagination sera bien mise à jour également.

DemoKeynote_part3_013

Après avoir cliqué sur “Ok”, si l’on fait un rafraichissement de l’application via la touche F5 :

DemoKeynote_part3_014

Karrie est bien passée en 2ème page vu que l’on affiche 3 par 3 le tout trié par ordre alphabétique sur les prénoms.

Note : à nouveau, cette partie est ultra-simpliste. Vous aurez bien évidement plus de boulot dans un scénario plus réel afin de gérer les concurrences d’accès, de résoudre les éventuels conflits côté serveur, etc. La documentation MSDN sur WCF RIA Services pourra alors vous aider.

4 – Pour terminer, nous allons voir les bases sur la mise en place d’un minimum de sécurité. Pour cela, nous allons travailler à travers un jeu d’attributs dédiés. Rendez-vous dans la partie serveur dans le fichier “FilmService.cs” contenant notre Domain Service. Le scénario va être le suivant : nous allons autoriser tous les utilisateurs (même anonymes) à pouvoir consulter la liste des acteurs mais nous n’autoriserons que les utilisateurs authentifiés à pouvoir effectuer une opération de mise à jour sur les acteurs. Pour cela, il faut se rendre sur la méthode UpdateActeurs() et la décorer de cette manière :

 [RequiresAuthentication]
public void UpdateActeurs(Acteurs currentActeurs)

Cela indique que seul les utilisateurs authentifiés pourront appeler cette méthode à distance via la couche RIA Services depuis le client Silverlight. Une fois cet attribut mis en place, relancez l’application, tentez d’effectuer des modifications et cliquez sur le bouton “Sauvegarder”. Voici l’erreur qui devrait être levée :

DemoKeynote_part3_015

Le message d’erreur en anglais est explicite. Maintenant, il faudrait être plus propre en récupérant mieux l’exception et testant l’error code 401 par exemple pour indiquer à l’utilisateur qu’il n’a pas les droits nécessaires.

Une fois logué, vous pouvez alors bien effectuer une mise à jour.

De la même manière, on peut filtrer les méthodes par rôle. Par exemple, nous allons désormais autoriser uniquement les utilisateurs membres du rôle “Admin” à pouvoir effectuer les mises à jour :

 [RequiresRole("Admin")]
public void UpdateActeurs(Acteurs currentActeurs)

Si vous n’êtes pas logué ou si vous êtes logué avec un compte non administrateur, vous aurez alors la même erreur que précédemment. Loguez vous cette fois-ci avec le compte “Administrateur” créé un peu avant pour pouvoir effectuer à nouveau les mises à jour. Ce dernier étant membre du rôle “Admin”, cela fonctionne à nouveau correctement.

Vous pouvez ainsi déjà commencer à contrôler les méthodes qui pourront être appelées ou non par les clients en fonction de leurs rôles et de leur niveau d’authentification. Vous pouvez également mettre ces mêmes attributs au niveau de votre classe entière Domain Service bien entendu.

Par contre l’expérience utilisateur dans ce cas-ci est relativement pauvre. En effet, on laisse l’utilisateur pouvoir effectuer certaines actions et ce n’est qu’après coup qu’on lui indique qu’il n’en a pas le droit. Il faudrait donc mieux afficher de manière contextuelle les différentes actions et écrans disponibles en fonction du niveau de rôle. C’est ce dont je m’étais occupé à faire à nouveau dans Cloudy Pizza et je l’avais expliqué en partie ici. Je m’étais pour cela fortement inspiré de ces 3 excellentes ressources (en Anglais):

- Silverlight 3 Navigation: Navigating to Pages in dynamically-loaded assemblies
- Silverlight 3 Navigation: Dynamically Loaded Pages… Now MEF Powered!
- Silverlight 3 Navigation: Even more on Dynamically Loaded Pages

Des ressources super intéressantes à lire et qui, j’en suis sûr, vous seront sûrement utiles un jour.

Si cela, vous intéresse, voici la solution Visual Studio 2010 complète contenant le résultat de ces 3 tutoriaux :

Enjoy !

David