Générateurs de substituts de test : NSubstitute vs Moq

by Laurent Yovanovitch 23. décembre 2015 02:12

Introduction

Cet article compare la syntaxe de deux générateurs de substituts de test pour .NET : le champion du monde Moq, qui règne depuis quelques années, et le challenger NSubstitute qui entend le détrôner.

Pour ce post, nous comparerons la syntaxe élémentaire des deux générateurs.

Que sont les substituts de tests ?

Les substituts de tests sont des outils pour l'écriture de tests unitaires.

Dans un test unitaire nous avons besoin d'isoler le code à tester. Il faut :
  1. instancier l'objet à tester.
  2. substituer les services appelés par la méthode à tester.
  3. suivant le niveau de test souhaité, vérifier les appels effectués sur les substituts
Exemple :
Considérons une classe business qui utilise un service par l'interface ICalculator.
Nous souhaitons tester le comportement de la méthode Compute de Business. Cette méthode appelle la méthode Add de ICalculator.



Nous souhaitons nous abstraire de toute implémentation de ICalculator afin que le test soit vraiment unitaire. Nous allons donc utiliser un substitut pour éviter d'utiliser une implémentation concrète de ICalculator. Voici comment peut s'écrire le test unitaire :
Quelques remarques :
  • les méthodes de gestion du substitut ne sont pas implémentées (elles sont soulignées en rouge). L'objectif de cet article est de comparer la syntaxe de deux bibliothèques de substituts.
  • la vérification de l'appel du substitut n'est pas nécessaire. Elle dépend de l'approche du test que vous adoptez (boîte noire / boîte blanche ou Inside-out / outside-in en TDD).

Syntaxe de base

Syntaxe de base avec Moq

Voici la syntaxe généralement bien connue avec Moq.

Avec Moq nous avons les particularités suivantes :
  • Instanciation explicite d'un objet Mock<ICalculator>
  • Setup utilise une expression pour spécifier la méthode à configurer
  • Lors de l'utilisateur du mock, il faut utiliser mock.Object
  • Verify utilise une expression pour spécifier la méthode à vérifier.

Syntaxe de base avec NSubstitute

Nous nous livrons au même exercice, cette fois avec NSubstitute.

Avec NSubstitute nous avons la syntaxe suivante :
  • instanciation directe d'un substitut par une méthode statique (factory), pas de new.
  • La référence du substitut a le même type que l'interface substituée.
  • Pour la configuration, écriture directe de la méthode sans passer par des expressions lambda.
  • Le substitut est utilisable directement pour l'instanciation de l'objet à tester.
  • La vérification se fait également sans expressions lambda.

Récapitulatif

Le tableau suivant récapitule la comparaison entre les deux bibliothèques, pour la syntaxe de base.

MoqNSubstituteVainqueur
instanciation de basenew Mock()Substitute.For();ex-aequo
type du substitutMockICalculatorNSubstitute (simplicité)
configuration de basesubstitute.Setup(mock => mock.Add(1, 2)).Returns(3);substitute.Add(1, 2).Returns(3);NSubstitute (simplicité)
utilisation de basesubstitute.ObjectsubstituteNSubstitute (simplicité)
vérification de basesubstitute.Verify(mock => mock.Add(1, 2));substitute.Received().Add(1, 2);NSubstitute (simplicité)

Finalement, au niveau de la syntaxe de base, NSubstitute tient toutes ses promesses et écrase le tenant du titre.

Et pour les fonctionnalités avancées ? Le titre sera remis en jeu lors de la revanche, en 2016 !

Tags:

Développement

Injecter plusieurs sources de données dans une classe

by Laurent Yovanovitch 19. décembre 2015 17:12

Introduction

Cet article explique comment refactoriser une classe business « classique » afin qu’elle puisse tirer ses données de plusieurs sources, dans un contexte d’injection de dépendances.

État initial

Nous avons une classe business « classique » qui récupère des données à partie d’une source.



La classe Business

La classe business possède une méthode Search qui renvoie des entités. Les résultats proviennent du repository IEntitySource injecté dans le constructeur.

L’interface IEntitySource et DatabaseEntitySource

L’interface IEntitySource expose la méthode Search. DataBaseEntitySource l’implémente en simulant un accès à une base de données.

L’interface IBusinessFactory et la classe AutofacBusinessFactory

L’objectif est ici de mettre en place l’injection de dépendances en l’absence d’une véritable application. IBusinessFactory possède une méthode Create qui a pour vocation de renvoyer une instance de Business. AutofacBusinessFactory implémente l’interface en utilisant un conteneur Autofac. Attention, ceci est un raccourci qui n’est pas à reproduire dans un vrai projet !



Le test de bout-en-bout

Le test bout-en-bout instancie AutofacBusinessFactory, appelle la méthode Search, et vérifie que les entités renvoyées sont bien celles qui sont renvoyées (en dur) par DatabaseEntitySource.

Exécution

Le test passe, la classe Business renvoie bien les données de l’IEntitySource qui lui a été passée.

Un nouveau besoin

Maintenant, le besoin change. Lors de la recette, le testeur dit « Ah, mais il manque des entités. Je ne l’ai pas dit, et ce n’est écrit nulle part, mais il faut afficher des entités qui ne sont pas dans la base de données. Et on ne peut pas les insérer. » La classe business va donc devoir renvoyer des données qui ne proviennent pas de DatabaseEntitySource.


Le test

J’écris un test pour exprimer ce nouveau besoin.

C’est le même test que précédemment, mais j’ai ajouté les entités « extra » 11 et 12. Évidemment, le test échoue.

Implémentation

Comment implémenter le nouveau besoin ? Nous avons actuellement la classe DatabaseEntitySource. On pourrait ajouter les nouvelles entités au résultat, mais cette classe est supposée renvoyer uniquement des entités présentes dans la base de données.

Il nous reste Business, et l’implémentation suivante :

Cette implémentation satisfait le test. (les autres tests échouent puisqu’ils sont restés sur la spécification initiale, sans entités supplémentaires)

Refactorisation

Cependant, l’implémentation n’est pas satisfaisante. Si plusieurs méthodes mettent en jeu les entités supplémentaires, il faudra y faire appel dans chaque méthode.

Pour supprimer la duplication nous introduisons une méthode GetExtraEntities

C’est mieux, mais la classe business n’a pas vocation à être une source de données. Les données devraient provenir d’une source de données. Nous allons donc introduire une nouvelle source de données

Refactorisation avec une nouvelle source de données

Nous introduisons une nouvelle interface IExtraEntitySource et une nouvelle classe ExtraEntitySource. La classe Business est modifiée ainsi :

L’interface IExtraEntitySource :

Et la classe ExtraEntitySource :

Nous modifions également AutofacBusinessFactory pour enregistrer ExtraEntitySource dans le conteneur. Le test passe de nouveau, et la classe Business fait son travail de traitement de données au lieu de les générer.

Réunification des sources

Il reste malgré tout quelques problèmes. Il y a une dissymétrie entre l’utilisation des deux sources de données. De plus, les deux interfaces IEntitySource et IExtraEntitySource sont identiques, ce qui est normal car on peut définir les entités « extra » comme « des entités qui ne sont pas dans la base de données ».
On pourrait donc abandonner IExtraEntitySource au profit de IEntitySource.

Le projet compile, mais le test ne passe plus.

Que s’est-il passé ? Le message d’erreur indique que le tableau renvoyé contient deux fois les données « extra », au lieu des données de base et des données « extra ». Le problème est ici lié à l’injection de dépendance. Dans AutofacBusinessFactory, nous avons ceci :

Les « ImplementedInterfaces » correspondent dans les deux cas à IEntitySource. Cela signifie que l’enregistrement de ExtraEntitySource écrase DatabaseEntitySource en tant qu’implémentation de IEntitySource. Lors de l’instanciation de Business, deux instances de ExtraEntitySource sont passées. On pourrait configurer le conteneur Autofac pour utiliser les deux classes, mais il y a une meilleure solution.

La relation implicite d’énumération

L’injection de dépendance introduit le concept de relation implicite entre les types. (cf. L’injection de dépendance introduit le concept de relation implicite entre les types. (cf. http://autofac.readthedocs.org/en/latest/resolve/relationships.html#enumeration-ienumerable-b-ilist-b-icollection-b et http://nblumhardt.com/2010/01/the-relationship-zoo/)

Ici, nous avons une relation d’énumération entre Business et IEntitySource : Business utilise une collection d’IEntitySource.

Autofac supporte implicitement cette relation*. Pour la mettre en œuvre, déclarer la dépendance en tant qu’IEnumerable dans le constructeur de Business :

On s’aperçoit que ceci simplifie énormément le code :

  • Repository et ExtraSource sont remplacés par l’ énumérable sources.
  • Dans les méthodes, SelectMany permet de fusionner les données renvoyées par toutes les sources
  • GetExtraEntities est supprimé
  • Cette implémentation permet de gérer un nombre indéfini de sources.

Le test passe de nouveau.

Conclusion

Il est possible d’utiliser la relation d’énumération dans les conteneurs d’injection de dépendance pour injecter les différentes implémentations d’une interface. Bien que ce schéma ne soit utile qu’occasionnellement, il permet des implémentations élégantes avec peu de modifications par rapport à l’injection d’une implémentation unique.

* La relation d’énumération est supportée par de nombreux autres conteneurs d’injection de dépendances, notamment Unity, Ninject et LightInject.

Tags:

Développement

Asp.Net 5 - VNext

by Gilles DEHAIS 14. décembre 2015 08:12

Asp.Net 5 appelé aussi VNext



Microsoft vient de sortir la Release Candidate d'Asp.Net 5 nommé aussi VNext. Cette nouvelle version est maintenant disponible en open source (disponible sur github), permettant à chacun de participer à l'élaboration et au développement d'Asp.Net.

Microsoft a revu entièrement son framework et son utilisation. VNext est plus léger, plus modulaire, disponible sur Linux, Windows et OSX via Visual Studio Code ou tout autre éditeur de code (même le bloc note...), optimisé pour le Cloud de Microsoft (Cloud Optimized). 

Le compilateur utilisé est le nouveau compilateur open source "Roslyn".

Avec VNext, il n'est maintenant plus indispensable de publier une application Asp.Net avec le framework entier. En effet, la librairie system.web est maintenant remplacer par des paquets Nuget. Chaque application Web peut maintenant être publier avec ses propres librairies (paquet Nuget) ce qui rend le déploiement et la maintenance de celles-ci plus simple et plus rapide. L'application crée sera lors de la publication de celle-ci, transformée elle même en paquet Nuget.

Il est quand même possible, pour des raisons de rétrocompatibilité, d'utiliser le framework complet. Ces frameworks ont été renommés comme ceci :

   - Framework complet : DNX50
   - Nouveau Framework VNext : DNXCore50

Nous allons maintenant lancer Microsoft Visual Studio 2015 pour découvrir plus précisément et en détail la nouvelle architecture des applications Web et leur utilisation.

La nouvelle arborescence de développement VNext dans VS 2015



Pour débuter, nous allons créer une application Web Asp.Net. Lors de la création de celle-ci, on remarquera que les modèles d'applications sont divisés en deux parties. Les précédents modèles qui utilisent l'ancien framework 4.6 d'Asp.Net et les nouveaux modèles (Empty, Web API et Web Application) qui utilisent le nouveau framework VNext. Choisissons un projet vide (Empty)


Une fois la création de notre application Web avec VNext, on se retrouve avec la toute nouvelle architecture de VNext.


Comme vous pouvez le voir, les fichiers web.config, csproj... n’existent plus. On a par contre plusieurs fichiers JSON (global.json, project.json) ainsi que le fichier Startup.cs, qui comme son nom l'indique, est notre point d'entrée de notre application Web.

Global.json



Le fichier global.json est un fichier qui contient les répertoires que le compilateur Roslyn doit compiler en temps réel. En effet, plus besoin de compiler puis rafraîchir la page Internet. Il suffit juste de faire les modifications dans le code, enregistrer et rafraîchir la page Internet. Le compilateur s'occupe de tout.

Nous pouvons donc lire que les répertoires "src" et "test" sont les répertoires qui seront compilés. Le répertoire "src" contient les sources de notre application et le répertoire "test" contiendra les tests unitaires.

Si l'on souhaite que le compilateur travaille sur un nouveau répertoire, il faudra le rajouter ici.


Emplacement des fichiers statiques (wwwroot)



Les fichiers statiques qui doivent être accessibles par les utilisateurs doivent être mis dans le répertoire wwwroot. Le serveur web est capable d'adresser ce répertoire contrairement au code source de l'application par exemple qui lui est en dehors de ce répertoire wwwroot.
Ainsi, seuls les fichiers dans ce répertoires seront consultables et en ligne. Le code de l'application (binaires) sera ainsi protégé.

Dépendances et références



C'est ici que vont se retrouver toutes les dépendances et références de votre application comme les librairies javascript, Grunt, Bower...) et les librairies utilisées. Elles sont gérés sous forme de packages Nuget. Ces dépendances/références sont rajoutées via un fichier Json appelé "project.json".
Elles sont représentées sous forme de hiérarchies de packages Nuget.


Pour importer une référence ou une dépendance, tout se passe dans le fichier "project.json" que nous expliquons ci-dessous.

Fichier "Project.json"



Le fichier project.json est le fichier qui représente toute votre application et qui remplace l'ancien csproj et web.config. Il permet de définir les dépendances, références, le ou les frameworks a utilisé, les scripts, les commandes, etc...

L'intellisence fonctionne dans ce fichier et permet d'installer et d'ajouter des packages Nuget sous forme de dépendances/références à votre application. 

Ainsi, si l'on tape "Microsoft." on s'aperçoit que Visual Studio nous propose une liste de package Nuget disponible au téléchargement. Puis, si on tape Microsoft.AspNet.Diagnostics":, Visual Studio nous propose les différentes versions de la librairie disponible et enfin, une fois la version renseignée et le fichier "project.json" enregistré, le compilateur va télécharger automatiquement le package Nuget et va l'installer dans notre application. On peut alors voir que le répertoire "référence" a été mis à jour automatiquement.


La version de la librairie est visible, ici la version RC final. On la retrouve dans les différents DNX (framework) référencés dans notre fichier "project.json". Il est aussi possible de ne pas définir une version de la librairie pour forcer le compilateur à prendre toujours la dernière version disponible du paquet Nuget de la librairie.

Aussi, les librairies n'ont plus à être mises dans les sources controls et ainsi le travail collaboratif s'en trouve facilité. C'est maintenant transparents par rapport au poste de développeurs, de livraison, de tests ect...

Le fichier Startup.cs



Le fichier statup.cs contient la méthode Configure qui permet de configurer le pipeline HTTP. Elle permet de charger uniquement ce que l'on souhaite et cela rend donc le tout plus léger.

On peut y utiliser des MiddleWares. Nous allons utilisé le MiddleWare de notre librairie Diagnotics récemment ajoutée et l'appelé via "app.UseWelcomePage();", pour afficher une simple page de bienvenue.


Ça y est notre première application VNext fonctionne.

Il est possible d'enrichir le pipeline avec plusieurs MiddleWare qui seront appelé et mis dans le pipeline à la chaîne mais aussi d'utiliser des composants comme React, Angular, faire du MVC avec la nouvelle version MVC6, ect....

Conclusion



Avec VNext, Microsoft a abandonné son ancien système de framework complet qui l'empêchait de mettre à jour facilement et régulièrement car il fallait alors réinstaller l'intégralité du framework sur les machines.
Maintenant, avec le nouveau découpage sous forme de paquets Nuget, les applications n'embarquent que les librairies dont elles ont besoin avec leur versionning. Microsoft peut donc ainsi publier des mises à jour de ses paquets plus facilement et plus périodiquement. 
La livraison de l'application est aussi facilitée car le serveur n'a plus besoin d'avoir le framework d'installé. L'application détient elle même les librairies (paquets Nuget) dont elle a besoin. Sa mise à jour en est elle aussi améliorée.
La nouvelle architecture VNext des applications est plus simple, plus flexible pour les développeurs et plus rapide grâce au nouveau compilateur Roslyn.

Tags:

Migrer les données SharePoint avec SHAREGATE

by scoignet 12. décembre 2015 12:12

1.1       Présentation de ShareGate

ShareGate permet de migrer le contenu d’un site SharePoint entre différentes versions de SharePoint. ShareGate supporte SharePoint 2003, 2007, 2010, 2013 et SharePoint Online.

Avec ShareGate, vous choisissez le niveau de granularité de la migration.  Vous pouvez migrez des collections de site en entier ou choisir ce que vous voulez déplacer : sites, bibliothèques, listes, les flux de travail, métadonnées.

1.2       Paramétrage de ShareGate

1-    Lancer l’outil ShareGate    

2-     Cliquer sur « Copie d’objects de site » pour migrer des sites / sous sites ou listes

Ou Cliquer sur « Copie de contenu SharePoint » pour copier des éléments de listes / des dossiers.

3-     Saisir les informations du site source et utiliser un compte qui dispose de tous les droits sur les bases

 

4-     Cliquer sur « Se connecter »

5-     Sélectionner le site ou sous site source et cliquer sur « suivant »

6-     Saisir les informations du site destination et utiliser un compte qui dispose de tous les droits sur les bases

7-     Cliquer sur « Se connecter »

8-     Cliquer sur le site de destination de la copie et cliquer sur « Suivant »

9-     ShareGate est paramétré.

 

1.3       Copie d’éléments

1-     Lancer l’outil ShareGate  

2-     Cliquer sur « Copie d’objects de site » pour migrer des sites / sous sites ou listes

Ou Cliquer sur « Copie de contenu SharePoint » pour copier des éléments de listes / des dossiers..

3-     Sélectionner le site ou sous site source et cliquer sur « suivant »

4-     Cliquer sur le site de destination de la copie et cliquer sur « Suivant »

5-     Dans le menu de gauche, sélectionné « sites » pour copier un site ou « Listes et Bibliothèques » pour copier une liste


6-      Dans le menu du milieu, sélectionner le nom de la « liste » ou du « Site » à migrer : Exemple : « Annonces » 

 

7-     Cliquer sur « copie»

8-     L’écran suivant s’affiche :

a.     Cocher « limiter aux » et saisir « 10 »

b.     Décocher autorisations personnalisées

c.     Décocher flux de travail

d.     Cliquer sur « copier » pour lancer la copie

 

9-     Dans le nouvel écran, sélectionner « Utiliser le mode silencieux » afin que la migration poursuivre malgré les avertissements et les erreurs sinon utiliser « Mode interactif » pour voir une pop up à chaque difficulté.

 

10-  Définissez la politique du mode silencieux puis « OK »

11-  Patienter le temps de la copie

12-  La migration est finis cliquer sur « Ouvrir le rapport » pour obtenir plus d’informations sur les échecs et réussites.


1.4       Utilisation des rapports de migration

1-     Sur le bouton « Rapport de migration »  dans le menu du haut 

2-     Cliquer sur le nom de la session du rapport à ouvrir « YYMMJJ-NUMBER »

3-     Dans l’écran suivant cocher « Afficher les items »  puis cliquer sur « Actualiser »

 

 

4-     Cliquer sur Filtré à côté de statut pour appliquer des filtres : exemple afficher que les éléments en erreur ou en avertissement. Puis cliquer sur « Actualiser »

 

5-     Le filtre affiche le résultat suivant :


6-     En double cliquant sur un élément ou en cliquant sur  dans le menu du haut, on peut obtenir plus d’informations:

La section lien d’aide offre un lien vers la documentation de ShareGate concernant l’avertissement / erreur.

 

7-     Il est possible d’exporter les résultats du rapport de migration dans un fichier excel, en cliquant sur l’icône    dans le menu du haut. 



 

Conclusion :

 

ShareGate est un outil payant dont le prix est compris entre 1995$ et 3995$ pour un utilisateur et entre 4995$ et 6996$ pour 5 utilisateurs.

Cet outil est simple d’utilisation et très efficace pour migrer le contenu de SharePoint d’une version à une autre en choisissant le niveau de granularité souhaité (un élément de liste, une liste, un site, une collection de site). ShareGate est utilisable sans installation sur les serveurs SharePoint.

 

ShareGate dispose de quelques inconvénients :  lenteur pour la migration, ne migre pas les éléments custom et nécessite un audit avant la migration.


Cet outil permet aussi de décider de garder ou non les permissions, de définir le nombre de versions à garder. ShareGate offre bien d’autres fonctionnalités à découvrir lors de son utilisation. 

Tags:

Collaboratif | Office 365 | SharePoint

Publier un application Windows 8 sur le Microsoft Store

by Gilles DEHAIS 13. novembre 2015 21:11
Nous allons voir, étape par étape, comment publier son application Windows 8 sur le Microsoft Store.


Création d'un compte Microsoft Développeur


Il faut d'abord avoir un compte Microsoft développeur. Nous allons donc nous enregistrer sur l'adresse suivante pour obtenir le compte développeur.



Remplissez les différents champs et choisissez le type de compte Individuel, qui est suffisant pour pouvoir poster votre première application Windows Store.

On vous demande ensuite de vous loguer avec votre compte Microsoft ou d'en créer un. Créer votre compte Microsoft si vous n'en disposez pas d'un déjà, sinon, loguer vous.

L'écran suivant permet le paiement du compte pour pouvoir accéder à la publication d'application.

Rentrez vos coordonnées bancaires ou payer via Paypal et accéder à l'écran suivant via le bouton "Suivant".

L'écran suivant vous indique le montant de votre facture et récapitule les éléments de votre compte.


Veuillez accepter les conditions générales du contrat de développeur d'application puis cliquez sur le bouton "Terminer".

Félicitation ! Vous pouvez maintenant accéder au tableau de bord pour pouvoir publier votre application Windows 8.


Publication d'une application


Dans votre tableau de bord, vous avez la possibilité de créer une nouvelle application. Cliquez sur le bouton illustré ci-dessous.
Pour pouvoir publier une application, il est nécessaire que celle-ci possède un nom unique. Il existe des millions d'application sur le store de Microsoft et elles doivent toutes avoir un nom différent pour pouvoir les distinguer. La page suivante permet de vérifier que ce nom est unique.


Taper le nom de votre application puis vérifier la disponibilité. Une fois votre nom unique trouvé, vous pouvez réserver ce nom via le bouton "Nom d'application réservé".

Vous vous trouvez maintenant sur le tableau de bord de votre application. Il permet de publier celle-ci, de gérer la publicité de votre application, ses incidents, son nombre de téléchargement, ses commentaires, ect...

Cliquez sur le bouton "Démarrer l'envoi" maintenant.

Vous voyez maintenant les différentes étapes à valider pour finaliser la publication.


Tarification et disponibilité


L'écran de tarification et disponibilité permet de mettre un prix à votre application. Si vous choisissez de rendre votre application payante, choisissez un prix de base. Vous remarquez qu'il est en dollar US. Il est possible avec l'option "marchés et prix personnalisés" de définir par pays la disponibilité de votre application ainsi que son prix dans la monnaie courante du pays.

L'option "Prix de vente" permet de faire des promotions sur une durée de temps pour votre application. Vous pouvez ainsi définir un prix inférieur au prix de base sur une période. Cette option sera disponible aussi lorsque votre application sera publier pour vous permettre de faire des promotions.

L'option "Distribution et disponibilité" permet de restreindre votre application à différents utilisateurs ou bloquer son téléchargement à tous les utilisateurs.

L'option "Familles d’appareils Windows 10" permet de bloquer l'application pour un ou plusieurs type d'appareil (PC ou Mobile style tablette ou téléphone).

L'option "Date de publication" permet de publier l'application à une date précise, manuellement ou dès la certification de l'application par Microsoft.


Propriétés de l'application


Cette écran permet de définir une catégorie définissant au mieux votre application. Si c'est possible, spécifiez aussi la sous catégorie pour pouvoir affiner la catégorie de votre application. Ainsi, votre application sera plus facilement trouvable par les gens qui sont intéressés par votre type d'application.

Pour éviter l'utilisation de votre application par des catégories d'âges, veuillez sélectionner un âge minimum. Cela permet de protéger les enfants d'images ou de contenus qui pourraient les choquer. Il est possible de la définir par pays. Veuillez-vous référer à la législation des pays pour rester dans la légalité dans ces pays.

Maintenant, définissez les prérequis matériels.Si votre application demande l'utilisation d'une caméra par exemple et que l'appareil de l'utilisateur n'en possède pas, il se verra afficher une alerte pour le prévenir qu'il ne possède pas le matériel nécessaire au bon fonctionnement de l'application.


Packages


Ici, vous devez soumettre à Microsoft les packages de votre application.


Description de l’application


Dans cette écran, vous allez décrire votre application aux utilisateurs qui la téléchargeront. Faites en sorte qu'elle soit la plus compréhensive possible et qu'elle reflète au mieux votre application.
Vous pouvez rajouter des captures d'écran de votre application pour illustrer et permettre à l'utilisateur de se faire une première idée de votre application. 
N'oubliez pas non plus l'icône de votre application. Elle sera utilisée pour afficher votre application dans le store.
Utilisez les mots clés pour permettre à votre application d'être le plus facilement trouvable lors de recherches par les utilisateurs sur le store.


Remarques pour la certification


Dans cette écran, vous pouvez ajouter des remarques pour les équipes de validation de Microsoft. Elles seront lues par Microsoft et vous pourrez ainsi expliquer certains processus de votre application comme fournir des login/mot de passe si votre application nécessite un compte pour pouvoir être utiliser.


Publication


Vous devriez avoir maintenant toute la liste de prérequis à la publication complet et valide comme ci-dessous.

Il ne reste plus qu'à envoyer sur le store Microsoft en appuyant sur le bouton "Envoyer au Store".


Vérification par Microsoft


L'équipe de Microsoft va maintenant vérifier votre application et passer en revu toutes les étapes de validation de Microsoft. Elle sera alors ensuite disponible sur le store de Microsoft. Cette validation peut prendre jusqu'à une semaine. Voici les différentes étapes disponibles dans votre tableau de bord de votre application sur le site de Microsoft. 
Elles vous permettent de suivre la progression de la validation de votre application.

Nous venons de voir toutes les étapes et prérequis qui permettent de publier une application Windows 8. Ces étapes sont identiques pour une application mobile ou desktop, que celle-ci soit pour Windows 8 ou Windows 10.

Tags:

Développement

Les nouveautés de WPF avec le framework 4.6, Visual Studio 2015 et Blend

by Gilles DEHAIS 19. octobre 2015 18:10
Avec la sortie du framework 4.6 de Microsoft, WPF a reçu son lot de nouveautés. Vous trouverez ci-dessous le listing non exhaustif des améliorations apportées par Microsoft à WPF.

Aperçu de définition

Il est maintenant possible de voir le code behind lié à un élément directement dans le code WPF. Pour cela, il suffit de faire un clic droit, puis "aperçu de la définition" sur n'importe quel élément WPF pour afficher son code behind.


Ici, on a utilisé l'aperçu de définition sur le Click du bouton. Il est aussi possible d'utiliser le raccourci Alt+F12.

Région WPF

Les régions sont disponibles dans le code WPF grâce au framework 4.6. Une région est représentée comme un commentaire mais permet de replier et déplier tout une région de code WPF.


Transparence des fenêtres enfants

Il est possible avec WPF et le framework 4.6 de créer des fenêtres enfants avec un effet de transparence. Pour cela, il est nécessaire d'avoir au moins Windows 8.

Dans notre exemple ci-dessous, nous avons créer une fenêtre parent nommée "MainWindow.xaml", une fenêtre enfant nommée "HUD.xaml" et ajouté un fichier app.manifest à notre projet. Voici le code à mettre dans le code behind de la fenêtre parente :


La transparence sera amenée par l'option "UserPerPixelTransparency" que l'on passe à "true". Il est aussi nécessaire pour que cela fonctionne de modifier légèrement le fichier manifest. Ainsi, on devra décommenter cette ligne dans le fichier manifest :


Notre fenêtre enfant "HUD" devient alors visible avec un effet de transparence.

Amélioration des affichages 

Microsoft a fortement amélioré l'affichage des éléments XML. Chaque élément est maintenant correctement dessiné par rapport aux DPI de chaque écran. Les échelles sont maintenant respectées.


DeferLoadStrategy (prochainement ajouté)

Microsoft devrait bientôt ajouté le chargement progressif des éléments WPF d'une page. Ainsi, l'application ne chargera en mémoire que les éléments affichés à l'écran. Il chargera ensuite, suivant les actions de l'utilisateurs, les autres éléments si nécessaire.

Cela permet une meilleur gestion de la mémoire et une meilleure expérience utilisateur.

Debugging avec Visual Studio 2015

Il est maintenant possible de debugger la partie WPF d'une application en temps réel. Microsoft a rajouté l'arborescence d'éléments visuels en direct (Life visual tree). 


Cette arbre permet de voir tous les éléments affichés dans l'application en cours d'exécution. Il est possible d'activer la sélection dans l'application en cours via le bouton . Dans l'application, sélectionnez l'élément graphique que vous souhaitez et l'arbre affichera et sélectionnera alors l'élément.

Vous pouvez aussi modifier via l'explorateur de propriétés en direct les différentes propriétés de l'élément sélectionné dans l'arbre d'éléments visuels


Ici, on a sélectionné une "grid". On peut ajouter ou modifier n'importe quelle propriété de la "grid". Nous avons choisi de rajouter un background à notre "grid" via le bouton "nouveau" et de sélectionner "background" et de lui définir la couleur rouge.


Si on retourne sur notre application, la grille ("grid") est bien devenue rouge.

Cette arbre d'éléments visuels est excellent pour pouvoir trouver un élément graphique rapidement dans notre code XAML (clic droit, afficher la source sur l'élément que l'on recherche dans l'arbre), de modifier ses propriétés et de voir le résultat sans devoir relancer l'application. Il suffira ensuite, de reporter dans le code ces modifications que l'on vient de tester car les modifications faites sur l'application via l'arbre ne modifie pas le code de l'application. Le design de l'application devient alors plus facile et plus rapide.

On peut aussi voir les "datacontext" des éléments XAML et ainsi régler les problèmes de binding plus rapidement.

Les nouveaux outils de diagnostic

Visual Studio 2015 apporte de nouveaux outils de diagnostiques. Ils sont disponibles dans le menu Déboguer, Démarrer les outils de diagnotic sans déboggage.


La chronologie de l'application est un outil nouveau et puissant dans Visual Studio 2015 car il permet de voir, par exemple, quelle partie du code peut ralentir le chargement de notre application.
Nous lançons notre application avec la chronologie et l'utilisation de l'UC comme diagnotics.


Nous pouvons voir que l'application met 5,19 secondes pour se lancer alors que la partie graphique met moins d'une seconde. Allons dans l'onglet "Utlisation de l'UC".


On peut voir que c'est notre méthode "MainWindow_Loaded" qui utilise 90% du temps de chargement. 
Nous mettons maintenant un point d'arrêt au début et à la fin de la méthode "MainWindow_Loaded" et lançons à nouveau l'application.


La nouvelle version de Visual Studio permet de voir le temps écoulé entre deux break points. Ici, le code met plus de 4 secondes pour s’exécuter. On peut alors remédier au problème facilement.


Maintenant, la méthode s'exécute en moins d'une milliseconde. L'application est chargée plus rapidement et l'expérience utilisateur est améliorée. Les données seront chargées plus tard en asynchrone par exemple.

Les nouveaux outils de diagnostic (la timeline pour Visual Studio 2015) permet de mieux appréhender ce qu'il se passe dans l'application et la corriger plus facilement.

Blend avec Visual Studio 2015

Blend est maintenant intimement lié à Visual Studio 2015. En effet, le projet se charge entièrement dans Blend et permet de modifier le code de l'application directement, exactement comme dans Visual Studio 2015.


De plus, lorsque l'on modifiait l'application dans Blend et que l'on revenait dans Visual Studio, Visual Studio affichait toujours une fenêtre pour savoir si l'on souhaite rafraîchir le code de notre application. Cette fenêtre s'affiche toujours mais avec une option supplémentaire.


L'option "recharger les fichiers modifiées sauf s'il existe des modifications non enregistrées" permet de mettre fin à l'affichage systématique de cette popup. Une fois sélectionné, on peut fermer la fenêtre par "Oui pour tout". Blend et Visual Studio se rafraîchiront alors automatiquement et d'une manière transparente, sans popup ennuyeuse...

De plus l'arborescence d'éléments visuel en direct (Live Visual Tree) est aussi disponible sous Blend. 

Microsoft souhaite, avec ces améliorations, que Blend devienne l'application principale pour créer et améliorer le visuel des applications WPF.

Conclusion

Ceci n'est qu'une liste non exhaustive des nouveautés apportées à WPF par Microsoft. De nouvelles fonctionnalités devraient voir le jour prochainement.

Tags:

Développement

Les nouveautés apportées par C# 6

by Gilles DEHAIS 15. octobre 2015 18:10
Avec la sortie de Visual Studio 2015, Microsoft a sorti une mise à jour de son langage C#, nommé C# 6. 
Voici les principales nouveautés apportées par cette nouvelle version du langage. 
Pour cette version la compilation est basée sur Roslyn, le nouveau compilateur open source C# et VB.Net

Cette liste peut être incomplète, sachant que Microsoft pourra ajouter des nouveautés à son au fur et à mesure.

Initialisation automatique des propriétés


Il est maintenant possible de ne plus avoir à initialiser les propriétés. C# 6 permet de les initialiser directement dans celles-ci.

Ci-dessous, sans le compilateur de C# 6, il est impossible de faire fonctionner le code car la propriété doit forcément avoir un setter pour être initialiser.

Avec C# 6, on peut initialiser directement la propriété et le setter devient alors superflu.

 

Les dictionnaires


Avant on pouvait instancier des dictionnaires tout en ajoutant des éléments dans ce dictionnaire.

Avec C# 6, nous pouvons toujours le faire mais le code permet une nouvelle méthode. En effet, Les accolades ont disparu pour faire place aux crochets.

Expression-bodied members


Cette nouveauté de C# 6 va nous permettre de créer des méthodes sur une seule ligne. Ceci est donc à privilégier sur des méthodes très simples. En effet, l’opérateur « => » permet de définir à une méthode en une ligne de code.

 

Cela ressemble à une expression lambda. D'ailleurs, le mot-clé « return » n’est pas utilisé non plus ici.

Await dans les blocs catch et finally


Le précédent framework, C# 5, a apporté le mot clé « await » qui permet d’attendre la fin de l’exécution d’une méthode asynchrone pour continuer à s'
exécuter. Malheureusement, il n’était pas possible de l’utiliser dans les blocs catch et finally.

Cette limitation est levée avec C# 6. On peut donc utiliser « await » dans tous les blocs comme le montre l’exemple suivant :

Les accès conditionnels

 C# 6 introduit un nouvel opérateur, « ?. », qui s’utilise exactement comme l’opérateur « . » mais qui ne lève pas l’exception NullReferenceException si l’objet précédent l’opérateur est null.

 

On peut voir ici que si Person est null, alors, l’opérateur renvoi null sans lever d’exception NullReferenceException. Si Person avant l’opérateur n’est pas null, il agit comme si nous avions mis un « . » et renvoie LastName.

Il est aussi possible de l'utiliser sur une collection, une méthode, un delegate, ect...

Filtre d’exceptions

Les filtres d’exceptions ajoutés dans C# 6 permettent d’écrire pour chaque bloc catch une condition d’exception. Ainsi, on peut capturer les exceptions en listant les blocs catch avec des conditions différentes. Cela évite les IF (Exception) dans les blocs catch comme on le faisait avant.

 

Une fois rentré dans un bloc catch, les autres blocs sont ignorés. On peut ainsi renvoyer une autre exception sans qu’elle soit capturée par les blocs suivants.

La lisibilité du code s’en trouve grandement améliorée. 

Les statics

Pour appeler des méthodes statiques, il n’est plus nécessaire de devoir écrire le nom de la classe pour avoir accès à ses méthodes.

Il suffit maintenant de déclarer dans les usings le namespace en utilisant le mot static ;

Puis d'utiliser les méthodes de la classe static importées directement :

C’est une évolution intéressante car elle permet de rendre le code plus simple et plus lisible. Cependant, elle peut porter à confusion dans certains cas et donc il faut éviter de l'utiliser trop systématiquement.

Le nouvel opérateur « nameof »


Cette opérateur, introduit par C# 6, permet de récupérer le nom d’un champ, d’une propriété, d’une variable ou d’une méthode sous forme d’une chaîne de caractères.

Voici une façon de l’utiliser :

D'autres nouveautés avaient été annoncées par Microsoft comme les params IEnumerable, les littéraux binaires et séparateurs de chiffres et bien d'autres, mais pour le moment, elles ont été enlevées de la version actuelle de C# 6. Elles seront peut-être disponibles plus tard.


Tags:

Développement

SharePoint 2013 : Design manager, c’est quoi ?

by scoignet 14. janvier 2015 12:01

Introduction

Convertir une page HTML en Master Page Sharepoint, cela est maintenant possible avec SharePoint 2013 ! 

« Design Manager » est un ensemble de fonctionnalités de SharePoint 2013.

Il vous aide dans la mise en place du design des sites SharePoint et vous permet d’utiliser vos outils habituels pour la conception du design du site.

Les deux fonctionnalités principales de « Design Manager »  présentées dans cet article sont :

-          Conversion de pages HTML en Master Page

-          Exportation / importation du package de conception (WSP contenant les composants graphiques : Master Page / images / CSS)


Prérequis

La fonctionnalité de publication doit être activée au niveau  Site Collection « SharePoint Server Publishing Infrastructure ».

La fonctionnalité de publication doit être activée au niveau  Site  « SharePoint Server Publishing».

 

Mise en place

L’accès au « Design Manager » se fait par deux moyens :

-          1ère solution : « Site Actions » puis « Design Manager » :


-          2ème solutions : « Site Actions » puis « Site Settings »


-          Puis « Look and Feel »  et  « Design Manager »


  1- Convertir une page HTML en Master Page

1.1   Introduction

Le « Design Manager » permet de faire du maquettage rapide avec le design fourni par un client (HTML /images/CSS). Le fichier HTML doit respecter certaines bonnes pratiques que nous allons voir dans le prochain chapitre.

 

1.2   Formater la page HTML

Le fichier HTML doit être formaté en respectant quelques régles :

-          Le dossier doit contenir un seul fichier HTML pour la conversion en Master Page

-          Le fichier HTML doit être conforme à la norme XML

-          Le doctype doit être en majuscule

-          Supprimer les balises <form> 

-          La balise <head> ne doit pas contenir de balise <style> 

-          La balise <script> doit être sur une ligne disctincte de son contenu.

 

Pour plus d’informations sur les régles à respecter aller sur le site suivant: http://msdn.microsoft.com/fr-fr/library/jj822370.aspx

 

1.3   Convertir la page HTML en Master Page

Etape 1 : Construire votre page HTML


Etape 2 : Télécharger les fichiers du design dans SharePoint

- Télécharger l’ensemble de votre dossier dans la bibliothèque de votre collection de site.
- Vous pouvez aussi utiliser SharePoint Designer pour parvenir à cette action.


Etape 3 : Sélectionner votre page HTML

-          Aller dans « Design Manager » puis « Edit Master Pages »  et «  Convert an HTML »


-          Puis « Séléctionner » votre page HTML.

SharePoint va convertir votre page HTML en masterpage.

 

Etape 4 : Visualiser votre master page 

Cliquer sur le lien pour obtenir un aperçu de cette masterpage


Etape 5 : Insérer les contrôles SharePoint

5.1 Cliquer sur « Snippets » en haut à droite

La masterpage est "brute" : la prochaine étape est d’insérer les contrôles SharePoint (menus, titre du site, webparts, …).

Ex : "Top Navigation" permet d’insérer un menu dans la Master Page.

 

5.2 Choisir le « Snippet » à insérer dans la Master Page

Cette page permet d’avoir un aperçu du contrôle, de personaliser ses propriétés et d’obtenir le code du contrôle à insérer dans votre page (HTML Snippet).


5.3 Insérer le snippet dans votre page

Copier le code dans votre page HTML à l’endroit souhaité, SharePoint convertira les modifications automatiquement dans la Master Page.

Etape 6 : Publier la Master Page

                               N’oubliez pas de publier votre Master Page, ceci est une erreur courante avec l’utilisation du « Design Manager ».

Votre Master Page custom est utilisable dès maintenant.

 

2 – Créer / importer un package WSP de design

Une autre fonctionnalité intéressante du « Design Manager » est la possibilité d’exporter ou d’importer un package contenant le design dans SharePoint (.WSP).

Exporter le package :

Etape 1 : Aller dans « Design Manager »

Etape 2 : Cliquer sur  « Create Design Package »


Etape 3 :  Cliquer sur « Create » et la solution sera génèrée

Etape 4 : Télécharger le package

La solution est disponible à cette adresse :

Site settings > Solution /_catalogs/solutions/Forms/AllItems.aspx


Importer le package :

Etape 1 : Aller dans « Design Manager »

Etape 2 : Cliquer sur  « Import a complete design package »


Etape 3 : Cliquer sur « Import »  et la solution sera importée

Votre design est prêt à l’emploi grâce à vos quelques clics de souris !

 

Conclusion :

« Design Manager » est un ensemble de fonctionnalités qui permet de transformer une page html en master page SharePoint 2013 et d’importer / exporter une solution de design.

La master page générée est de type publication et ne fonctionne pas pour les autres types de sites sans activer la fonctionnalité de publication ou d’apporter un certain nombre de modifications à la master page.

La fonctionnalité « package de conception » de SharePoint 2013 (création de la WSP du design dans SharePoint)  ne doit pas être utilisée en production car quelques bugs existent encore lors de l’import / export du design SharePoint (plus d’informations ici et ). Il est donc recommandé de faire soi-même le package en se créant une solution SharePoint avec Visual  Studio pour pallier ses bugs. En revanche, pour effectuer du maquettage rapide d’un site cela est pratique.

Une fois ces quelques bugs et le processus maitrisés, « Design Manager » permet une mise en place rapide d’un design html dans SharePoint. La phase la plus longue est d’adapter les CSS de l’existant (design HTML) pour être en adéquation avec ceux utilisés par SharePoint. Le gain de temps entre partir de zéro (master page par défaut de SP) ou en utilisant cette fonctionnalité de SharePoint est discutable.  

Tags:

Collaboratif | Développement | HTML | SharePoint

Project Online and Reporting

by sgross 8. janvier 2015 15:42

Introduction

Reporting is one of the most important part of a Project and Portfolio Management system.

With Project Online, the way to build and publish report has changed. It can be difficult to find complete documentation about this topic.

This post has been written to help readers to build their Reporting solution for Project Online. Not all the details will be given, but the author tried to draw the big picture of the solutions, with some practical advices based on real world experience in Project Online deployement for Customers.

I would be very happy to answer questions you can have after you read this post: return of experience, additionnal questions, ask for POC environment, etc…

You can contact me on tweeter: @SylvainGrossNeo, or mail: Sylvain.Gross AT neos-sdi.com

Project Online

Project Online is the Office 365 service proposed by Microsoft, designed to manage Projects and Portfolios (PPM).

With Project Online, companies can manage their projects with Project Server, without supporting the maintenance cost of a multitier infrastructure.

Users continue to use Project Pro (for Project Leader) or PWA (for all other users): there is no difference for them.

For Project Administrators, there are some differences to take into account:

  • Customization: with Project Server, it is possible to use PSI to create extensions (server event handler, enhanced statusing form…). With Project Online, PSI is not allowed, developer must use the client side object model (CSOM)
  • Reporting: with Project Server, we have access to both relationnal database, or OLAP database to get data. Reports can be developed with SQL Server Reporting Services (SSRS). With Project Online, there is no access to the Database: we have to get the data through another way. This point will be developed in the next chapters.

For a complete list of differences between Project Online and Project Server 2013, follow this link: http://technet.microsoft.com/fr-FR/library/dn268595(v=office.15).aspx

The examples below will be based on our Project Online demo tenant. If you don’t have one, contact me, to see how we could do (access to Neos-SDI tenant, or ask for a POC tenant for your company).

Project Online and Data Access

Principle

With Project Online, there is no possibility to execute T SQL statement and get data from relational database, or Analysis Services database. Because we are in a cloud architecture, this limitation is easy to understand.

The solution to get data from your Project Online platform is OData.

OData

The simplified definition of OData is: The Open Data Protocol (OData) enables the creation and consumption of REST APIs, which allow resources, identified using URLs and defined in a data model, to be published and edited by Web clients using simple HTTP messages.

It means that you have to send HTTP message, and you get your data. For example, if our Project Online URL is https://neossdistaffing.sharepoint.com/sites/pwa, we have to add /_api/ProjectData/Projects to get the list of projects.

The basics of OData for Project Online

By typing https://neossdistaffing.sharepoint.com/sites/pwa/_api/ProjectData/Projects (replace neossdistaffing by your tenant name) in the URL of Internet Explorer, you will get something like that (I reduced the number of fields to simplify).

<?xml version="1.0" encoding="utf-8" ?> 
- <feed xml:base="https://neossdistaffing.sharepoint.com/sites/pwa/_api/ProjectData/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <id>https://neossdistaffing.sharepoint.com/sites/pwa/_api/ProjectData/Projects</id> 
  <title type="text">Projects</title> 
- <content type="application/xml">
- <m:properties>
  <d:ProjectId m:type="Edm.Guid">32988321-c6be-e111-9f1e-00155d022681</d:ProjectId> 
  <d:EnterpriseProjectTypeName>Software Development</d:EnterpriseProjectTypeName> 
  <d:ProjectAuthorName>i:0#.f|membership|admin@neossdistaffing.onmicrosoft.com</d:ProjectAuthorName> 
  <d:ProjectDescription>Helps users evaluate their intake, exercise, and lifestyle behaviors to produce an action plan to discuss with a doctor. Offers a “health-o-matic” meter to measure the user’s health status.</d:ProjectDescription> 
  <d:ProjectDuration m:type="Edm.Decimal">3257.998333</d:ProjectDuration> 
  <d:ProjectName>Health Assessment Reporting Tool</d:ProjectName> 
  <d:ProjectOwnerName>Sara Davis</d:ProjectOwnerName> 
  <d:ProjectPercentCompleted m:type="Edm.Int16">25</d:ProjectPercentCompleted> 
  </m:properties>
  </content>

Projects, and what else ?

In the previous example, we asked for Projects. There are many other entities: to get the list of entiries, simply type:

https://neossdistaffing.sharepoint.com/sites/pwa/_api/ProjectData

CaptureList Segments

Be more selective

When we asked for Projects data, we received a lot of information about the projet. There are more or less 100 fields in the Project entity: basically, we don’t need all the details !

We can use OData query language to select specific fields, to filter data, or order the resultset. This example selects only some fields of the project, thanks to the $select clause.

https://neossdistaffing.sharepoint.com/sites/pwa/_api/ProjectData/Projects?$select=ProjectId,ProjectName,ProjectActualWork,ProjectFinishDate,ProjectRemainingWork,ProjectWork

For more information about OData querying:

Consuming OData

Now that we can get data from Project Online, we need a solution to create reports. The immediate solution is to use a well known Microsoft Product: Excel !

Excel will allow us to:

  • Defining the different OData datasources
  • Using Power Pivot to create relations between entities
  • Using Pivot Table, graphical, tables or Power View to create reports

Initializing Excel

The next examples will use Power Pivot. It’s an Excel Addin: you should verify if the Addin is activated. This Addin is installed with Excel 2013 in the Professional Plus edition.

For Excel 2010, Power Pivot can be downloaded and installed: Bing or Google should find the URL Clignement d'œil

Often, Power Pivot and Power View are not activated. To activate them, go to the Excel Backoffice, and Manage COM Addins.

Capture Activer PowerPivotView

After activation, the Addins should be present in the ribbon.

Capture Ruban Power Activé

Create the Datasource

Before integrating the Datasource in the Excel Report file, you should design and code your OData query. Keep in mind that each field will generate a significative volume of data, especially for entities like Tasks, Assignments, or Timephased data. In this last case, each field must be carefully weighted, because the field will be added to each row: only relevant fields must be queried, if you want to keep acceptable response time.

In our example, we willl stay simple: the previous Projects query, with some fields. You can check the result in the navigator. Please note the you have to desactivate an option in Internet Explorer, if you want to see the XML Data in the Browser. The RSS Feeds must not be read by the browser (Option / Content / Advanced / Uncheck Activate RSS Feed readmode)

https://neossdistaffing.sharepoint.com/sites/pwa/_api/ProjectData/Projects?$select=ProjectId,ProjectName,ProjectActualWork,ProjectFinishDate,ProjectRemainingWork,ProjectWork

If you’re happy with your OData query, it’s time to integrate it in your new Excel Report, created in a new Excel workbook.

In your new workbook, go to Data, and insert an Other Data Source, and select OData.

Insert OData DatasourceIn the dialog box, paste your OData query.

Capture OData Query

The table Projects is proposed: we can accept it.

Capture OData Query Step 2

We can give an explicit name to the connection, and to the ODC file (Office Data Connection).

Capture OData Query Step 3

We can choose now how to use the data:

  • Table: the data will be displayed in a new Table in the current workbook
  • Pivot Table: the data will be added in a pivot Table, to perform manalysis
  • Graphical Pivot Table if we want to display graphics
  • Power View Report
  • Only connection creation

In all of the cases, the data will be added in the Power Pivot datamodel: this will be the most interesting thing. In practice, in the most often case, we will choose the last option, because we will need to enhance the model, by adding other entities like tasks, resources or assignments before drawing the report.

Capture OData Query Step 4

Enhance the Data Model

If you select the Power Pivot tab, you can access to the data model.

Capture Data Model Step 1

If you click on Manage, the very simple Datamodel is displayed. It does only contain one table: Projects. The data are displayed as if we were in a normal Excel sheet. But be aware that we are in Power Pivot. In fact, the data are cached into the Excel file, even if they are not present in an Excel sheet.

 image

From here you can modify the model, by adding calculated columns. One common operation should be to add a Work in Days, or to have column with a more user friendly name.

By clicking on the last column, you can add a formula, in the DAX language. In this example, we will calculate the Project Work in days, by dividing by 8.

Capture Data Model Step 2

Help on DAX expressions can be found here: http://msdn.microsoft.com/fr-fr/library/gg399181.aspx

Note that there are a lot of assistance to build you queries in the formula bar.

Another possibility is to hide some technical column for clients: for example ProjectId should not be shown in the Excel sheets. A simple right click will propose this option.

Create relationships

The main benefit of Power Pivot in Project Online context is the possibility to create relations between related entities. Because OData query will only propose to get data table by table, we are loosing the relations that would be present in the Relational Datamodel in SQL Server. Even if OData query can give access to navigation between related table (expand, parent, etc…), it’s more difficult than a INNER JOIN…

One usage example is to get the Tasks by Project. To make it, we have to add the Tasks table in the datamodel, and add a relation between the 2 tables, through the ProjectId key.

To establish this relation, we have to:

 

Capture Data Model Step 3

  • Create the relation

Capture Data Model Step 4

The model is now complete: it’s time to use the report in Excel.

Additional information about Power Pivot can be found here: http://msdn.microsoft.com/fr-fr/library/gg413497(v=sql.110).aspx

Project Online Reporting

If we return on Excel, the worksheets are empty: we did only work with the Power Pivot model.

We will now consume this datamodel to create report tables and graphical reports. There are different ways to create this reports.

Simple table

If we want to consume only data from a single table, we can use standard Excel tables. To insert such a table, simply go to Data / Existing Connections /  Tables

Capture Reporting Step 1

After that, you will have a simple tabular view of your data, where you could make conditional formatting, using databars, smileys, etc…From here it’s standard Excel knowledge.

Pivot Table

Very often, the reports must display data from many tables. You can create pivot tables to achieve this kind of report. To create this report, in the previous Existing Connection dialog box, select “Tables in the Datamodel”. After the model is declared in this worksheet, you can drag and drop each field, regardless the table it belongs.

Capture Reporting Step 2

Graphical Reports

It’s easy from this data to create graphical: again, it’s standard Excel usage. You can use slicers, bar graphs, etc…All the power of Excel is available build very powerfull reports.

Capture Reporting Step 3

Publishing Reports

The reports produced with Excel can be shared in the organisation through Excel Online.

We only have to save the Excel Report in SharePoint Online to make it available for the company.

A good place to publish reports will be the Reports part of Project Online.

Capture Publishing Step 1

Your new report can be dragged and Dropped in a SharePoint folder in the BI Center. Alternatively, you can save it from Excel, and modify the display option (selection of displayed sheet, parameters…).

Capture Publishing Step 2

If you return in the library, and you click on the report, it will directly be displayed in an Excel Viewer.

Capture Publishing Step 3

The report can also be displayed in another site: you just have to add a Excel Viewer webpart to your page, and the report will be available in the site. A good practice is to let the Excel document in the BI Center, and to display it through this webpart: it’s better than copying the report on each site !

Refreshing Reports

Of course a report is not aimed to be static: the data should change. There are different options:

  • Manual update from Excel: it’s necessary to load the file, update through the Refresh All command, and save the updated file
  • Manual update from Excel Online: the process is the same, except that you don’t have to load the file in Excel. Don’t forget to Edit the workbook before asking for the Refresh, otherwize the Refresh operation will not modify the Excel File, but just the page
  • Auto Refresh update, with Power BI. It’s on optionnal service of Office 365: at least one person must subscribe to the service to use Power BI.

Manual Update

In Excel, the process is obviuous: Open the file, clic on Refresh, and save the document. The data will be updated.

In Excel Online, first you must Edit the file:

Capture Refresh Step 1

After that, you can Refresh All Connections

Capture Refresh Step 2

A warning will ask you to confirm, because of security risks. After confirmation, the report is grayed while the report is being refreshed. Note that the execution time can not exceed 10 minuts, otherwize you will get a timeout error. Microsoft support confirmed that this timeout duration cannot be changed in Office 365 for a specific tenant.

The data are then updated for all users.

Please note that a feature must be activated in your PWA collection: Project Web App Permission for Excel Web App Refresh.

To activate this feature, go to Site Settings / Site Collection Feature and activate it

Capture Refresh Step 3

 

Automatic Update in Power BI

Manual update off reports is not very convenient if you have a lot of reports. There is a risk of un refreshed report, showing old data.

A solution exists to update the reports automatically: Power BI.

Power BI is a complete Microsoft offer, to help companies to give value to their data. The different modules are:

  • Power BI Sites for centralizing and sharing Reports and data connection
  • Gateway management for helping you to expose your On Premise data to internet, in OData format. This allows you to build reports with both On Premise data, and Cloud data
  • Power BI Q&A for querying your data with natural language

The official link to Power BI is: http://www.microsoft.com/en-us/powerBI/default.aspx

In our case, we only use Power BI Sites

When Power BI is activated in your Office 365 tenant (you can request a trial period on your existing Office 365 platform), you will have Power BI in your Site Content.

Capture Auto Refresh Step 1

If you click on Power BI, you will be moved to another site: the Power BI Site.

This site will analysing your collection, and display its content. You will see different Folders: PWA Data Connections, PWA Reports, etc…All the content of the BI Center will be shown.

Our report is stored in the PWA Reports folder.

Capture Auto Refresh Step 2

A SharePoint icon is displayed over our report. It means that this report has not been Enabled in Power BI. So let’s make it:

Capture Auto Refresh Step 3

After confirmation, the Enabling process runs, and takes few seconds. After that, you can close the dialog (not Open).

Now, the report has wysiwyg aspect.

Now we will schedule the Auto Refresh. For that, click again on the Ellipsis, and select Schedule Data Refresh. Previously, you can add the report to the Features report, and to the Favorite: it will make your life easier when you will access to the report later.

Capture Auto Refresh Step 4

The next page will let you setup the Auto Update process.

Capture Auto Refresh Step 5

You must test the connections before moving forward. This test process will raise an error for all the connections. I have no explanation why, seem to be a language problem: I was not able to find a solution: I will update this post as soon I will get a solution.

Nevertheless, even after this error, we can save the settings, and the update will work.

Clic on Save and Refresh Report, or Save settings, and the update will be queued.

If you clickk on History, you will see the Update process. Depending on the schedule time, the document will be updated.

Be sure that your Excel document is not opened somewhere when the Refresh is scheduled, otherwize Power BI will not be able to check out, modify and Save the Excel document. If the Refresh Process fails, it will be automatically retried.

When the Update is successfull, the status will be marked as We’ve refreshed the data successfully.

Capture Auto Refresh Step 6

Conclusion

Project Online is a very interesting solution for Project and Portfolio Management.

An important limitation was the reporting, because of the unavailability of SQL Server database.

Different answers can be proposed, with one of the most used software: Excel.

Depending of the level of automaticity each company wants, complete the subscribtion with at least one Power BI licence for the administrator is a very efficient option.

In Neos-SDI, we have already implemented a lot of Project Online solutions for customers, with very different Reporting needs. For each case, a solution was found to meet their requirements.

Tags:

EPM | Business Intelligence | Cloud | Office 365

Project Server 2013: edit Project Custom fields from Project Center (English Version)

by sgross 23. juin 2014 20:24

This article explains how to simplify Project Custom Field Update, directly from Project Center (in place edition). With this method, only 2 clics are necessary to update a KPI. With the standard method, more than 1 minute would be necessary. Source code is provided, and available for your specific needs.

This post is a translation from the original post written in French, further to some readers feedback.

In case of question or comment, you can contact me on twitter: @SylvainGrossNeo !

The code has been inspired by the Project 2013 SDK, and a postfrom @MartinLaukkanen.

Project Indicators

To improve the communication on projects, we often use Project Custom Fields: KPI’s like Project Health, Project Schedule, Project Cost, etc…These visual KPI’s will be readable in Project Center, were the whole portfolio is displayied, with the main figures: start/finish date, % achievement, etc…

Diffferent views can be defined in the Project Center, letting you the possibility to highlight relevant information, for exemple KPIs.

A Project Center displaying a lot of projects with red KPIs will require some attention from the PMO’s and executing directors !

image_thumb2

 

Updating Indicators

To update these KPIs, project leader have different possibilities:

  • A Project Detail Page: a web form available from PWA, where you can update Custom Fields
  • From Project Professional, he cans edit the Information of the project, including Custom Fields

image_thumb6

Those who are used to work with indicators will certainly confirm that those process a bit long: go to the project center, edit the project, select the PDP, change the value, save, archive…are long operations. If the Project Leader has to update many projects, he will waste a lot of time.

On viewing perspective, the above screenshot confirm that the graphical rendering is very basic: we can choose betweenn the words Red, Green, Yellow…It’s only in the Project Center that the indicator will be displayed with its graphical attributes.

In order to help one of my customer, I imagined and designed a different way to update the KPI’s: make the Project Center editable. The screenshoot and the video below shows briefly how it works. with a Project Health indicator.

image_thumb9

Small video (direct link here for fullscreen):

Changer le Project Health directement depuis Project Center

 

A writtable Project Center ?

The idea could seem to be stange: make the Project Center editable. But after a thinking time, we notice that the project center is just a web page…with some specificities!

To make the Project Center “writtable”, we “just” have to:

  • Know how to react on a cell click
  • Display some choices depending on the content to edit: smileys, text…
  • Know how to manage the user selection
  • Know how to update the project, with this new value
  • Nice to have: make it work in an instance of Project Online, not only On Premises. 

Clic on a cell in the Project Center

To manage the clic on the Project Center, we have to connect to the JSGrid of Project Center. After that, we have to attach to the Click event, to display the content, and propose the 3 choices (colors).

In the Project Server 2010 SDK, a starter kit proposed to customize the Project Center. This kit has not been updated for 2013, because the SDK is more focused on the new features like JSOM/CSOM (OM means Object Model).

Choose the cell, and clic on the indicator

In case of clic, we will simply have to replace the InnerHTML of the cell with ours: a list of IMG tags, with javascript eventhandlers.

Update the Project

In JSOM, the JS means Javascript: it is now possible to modify projects, resources, etc… in Javascript, on client side !

The second benefit is of course to allow Project Online customisation: because in this case we cannot access to WCF and PSI.

In CSOM or JSOM, the main challenges are:

  • asynchronous programming model, callbacks…
  • poor documentation

To update the project, we will need to:

  • Kwow which value has been selected
  • Get the value in the look up
  • Transform the value into its internal name
  • Publish the modified

The code

Disclaimer: the provided code is not ready for production. It’s more a explanation of the concept, and need to be developed, improved, industrialized…before putting in production..

The basics

All this code is written in Javascript, and is stored in a single js file.

To be integrated, different possibilities:

  • Create a SharePoint solution, including a feature.The layout folter will contain all the source code. I used this method because of the ease of debug. Follow this link the have more details: SDK here, and  this threadto start. 
  • Modify the Project Center, and integrate a Content Web Part, and paste the code inside.
  • Copy the JS in the Styles forder of the site, and reference the code is the project center. This method whould be used for Project Online instance.

OnClick

This following code is an adaptation of the PS2010 SDK.

http://msdn.microsoft.com/en-us/library/ff535984(v=office.14).aspx

/// <reference name="MicrosoftAjax.js"/>
/// <reference path="~/_layouts/inc/pwa/library/Utility.debug.js"/>
/// <reference path="~/_layouts/inc/pwa/library/WebMethodManager.debug.js"/>
/// <reference path="~/_layouts/inc/pwa/library/shell.debug.js"/>
/// <reference path="~/_layouts/inc/pwa/library/TimesheetSatellite.js"/>
/// <reference path="~/_layouts/inc/pwa/library/RemoteTextConv.debug.js"/>
/// <reference path="~/_layouts/inc/pwa/library/ProjectFramework.debug.js"/>
/// <reference path="~/_layouts/inc/pwa/library/GridSatellite.debug.js"/>
/// <reference path="~/_layouts/inc/pwa/library/projectserverscripts.debug.js"/>
/// <reference path="~/_layouts/inc/pwa/library/pagepropertymgr.debug.js"/>
/// <reference path="~/_layouts/SP.core.debug.js"/>
/// <reference path="~/_layouts/JsGrid.debug.js"/>
/// <reference path="~/_layouts/JsGrid.Gantt.debug.js"/>
/// <reference path="~/_layouts/sp.runtime.debug.js"/>
/// <reference path="~/_layouts/sp.debug.js"/>
/// <reference path="~/_layouts/ps.debug.js"/>
var pc; // Contains the Project Center extension object.
var JsGridControlInstance;
var JsGridSatellite;

var projContext;
var customFields;
var projects;
var customFieldData = [];
var currentProjectUid;
var currentIndicatorValue;
var currentCell;
var fieldName;
var lookupEntries = [];

_spBodyOnLoadFunctionNames.push("ProjectCenterMain");

function ProjectCenterMain() {
    pc = new ProjectCenterExtension();
    fieldName = 'Project Health';
}

function ProjectCenterExtension() {
    if (typeof projectCenterComponent === 'undefined')
        return;
    JsGridSatellite = projectCenterComponent.get_GridSatellite();
    JsGridControlInstance = projectCenterComponent.get_GridSatellite().GetJsGridControlInstance();
    JsGridControlInstance.AttachEvent(SP.JsGrid.EventType.OnSingleCellClick, CellClicked);
}

Cell choice et clic management

The purpose is to replace the InnerHTML content, with a liste of IMG tags.

function CellClicked(eventArgs) {
    currentCell = eventArgs.eventInfo.target;
    currentProjectUid = eventArgs.recordKey;
    //alert('Salut monde !');
    eventArgs.eventInfo.target.innerHTML = '' +
        '<img onclick=\"SelectIndicator(\'' + currentProjectUid + '\',\'Red\');\" width=\"16\" height=\"16\" title=\"Red\" style=\"border: 0px currentColor; margin-right: auto; margin-left: auto; display: block; max-height: 16px; max-width: 16px;\" src=\"/_layouts/15/images/../inc/pwa/images/cf_2p.png\"/><BR/>' +
        '<img onclick=\"SelectIndicator(\'' + currentProjectUid + '\',\'Yellow\');\"width=\"16\" height=\"16\" title=\"Yellow\" style=\"border: 0px currentColor; margin-right: auto; margin-left: auto; display: block; max-height: 16px; max-width: 16px;\" src=\"/_layouts/15/images/../inc/pwa/images/cf_1p.png\"/><BR/>' +
        '<img onclick=\"SelectIndicator(\'' + currentProjectUid + '\',\'Green\');\"width=\"16\" height=\"16\" title=\"Green\" style=\"border: 0px currentColor; margin-right: auto; margin-left: auto; display: block; max-height: 16px; max-width: 16px;\" src=\"/_layouts/15/images/../inc/pwa/images/cf_0p.png\"/><BR/>';
}

 

Lookup loading

We keep in mind UID of Project, and the selected value. Now let’s load the custom fields. In case of lookup, the different states must be stored.

function SelectIndicator(projUID, color) {
    currentProjectUid = projUID;
    currentIndicatorValue = color;
    ProcessProject();
}

function ProcessProject() {
    projContext = PS.ProjectContext.get_current();
    customFields = projContext.get_customFields();
    projContext.load(customFields);
    
    projContext.executeQueryAsync(getCFComplete, getCFFailed);
}

function getCFFailed(sender, args) {
    alert('Boum');
}

function getCFComplete(response) {
    var cfEnumerator = customFields.getEnumerator();
    while (cfEnumerator.moveNext()) {
        var cf = cfEnumerator.get_current();
        // Ajout à la liste des customFields

        customFieldData.push({
            Id: cf.get_id(),
            Name: cf.get_name(),
            InternalName: cf.get_internalName()
        });
        // S’agit il de notre Custom Field, et s’agit il d’un lookup ?
        if (cf.get_name() === fieldName) {
            var lookupTable = cf.get_lookupTable();
            // Prépare au Chargement de la lookup de ce custom field
            projContext.load(lookupTable);
            // Le code qui suit va s’exécuter en asynchrone, à l’aide d’une fonction anonyme

            projContext.executeQueryAsync(function () {
                var ltEntries = lookupTable.get_entries();
                // Recherche les valeurs de la lookup
                projContext.load(ltEntries);
                projContext.executeQueryAsync(function () {
                    var ltEnum = ltEntries.getEnumerator();
                    while (ltEnum.moveNext()) {
                        var ltEntry = ltEnum.get_current();
                        // Stocke chaque élément de lookup dans le tableau, en incluant son InternalName
                        lookupEntries.push({
                            InternalName: ltEntry.get_internalName(),
                            Value: ltEntry.get_value(),
                            FullValue: ltEntry.get_fullValue(),
                            Description: ltEntry.get_description()
                        });
                    }
                }, getCFFailed);

                // Lorsque la lookup et le custom field sont chargés, on va charger les projets
                GetProjects();
            }, getCFFailed);
        }
    }

 

Load project, and Update

The project load works asynchronously. The UpdateProject method is called. The internal UID must be found for the different( lookup entries. The  setCustomFieldValue function waits for something like that::

PS.DraftProject.setCustomFieldValue(
   'Custom_x005f_abc8d78a1f5e211940b00155d000a03',
    ['Entry_abc76e70a1f5e211940b00155d000a03']);)

We need to do some work to make it work….…

function GetProjects() {
    projects = projContext.get_projects();
    projContext.load(projects, "Include( Name, CreatedDate, Id, IsCheckedOut )");
    projContext.executeQueryAsync(updateProject, getCFFailed);
} 

function updateProject() {
    var projectId = currentProjectUid;
    var project = projects.getById(projectId);
    var draftProject = project.checkOut();


    // Retrouver le Custom Field à l’aide de son nom
    var cfData = $.grep(customFieldData, function (val) {
        return val.Name === fieldName;
    });
    // Retrouver la valeur du Lookup choisi
    var leData = $.grep(lookupEntries, function (val) {
        return val.Value === currentIndicatorValue; //"Red"; 
    });
    // Retrouve l’Id et donc son InternalName
    if (leData.length > 0 && cfData.length > 0) {

        // La méthode setCustomFieldValue attend le lookup sous forme de Tableau, d’où la syntaxe un peu spéciale.
        var lookupInternalName = [leData[0].InternalName];
        draftProject.setCustomFieldValue(cfData[0].InternalName, lookupInternalName);
    }
    // Ce code permettrait de gérer le custom fields non lookup
    else if (cfData.length > 0) {
        draftProject.setCustomFieldValue(cfData[0].InternalName, "Ma valeur de CF");
    }
    //Publication
    var publishJob = draftProject.publish(true);
    //Attente de fin de traitement avec analyse du code de retour
    projContext.waitForQueueAsync(publishJob, 30, function (response) {
        if (response !== 4) {
            alert('Erreur dans la publication du projet:' + response + '. Pour une liste des codes, se rendre sur http://msdn.microsoft.com/en-us/library/office/microsoft.projectserver.client.jobstate_di_pj14mref(v=office.15)');
        } else {
            // En cas de publish correct, la page est rechargée (à optimiser par un refresh coté JS)

            location.reload(true);
        }
    });
}

Test and Debug

The easiest way is certainly to work with a “local” Project Server 2013 and use breakpoints in order to understand what is happening.

To work, the Project Center must reference some JS, through a Content Web part.

image_thumb21

In case of emergency: Twitt me @SylvainGrossNeo !

Tags:

Neos-SDI  Neos-SDI