vendredi 30 décembre 2016

Build + code coverage + Deploiement ASP.NET Core MVC avec TFS 2015 On Premise

Comme vous le savez surement, ASP.NET Core MVC s'intègre bien avec Azure, et donc orienté Cloud. Ainsi, les composants et modules des builds et Release dans Azure ont été conçu en priorité pour les applications en .NET CORE. Ce n'est pas encore le cas sur la monture TFS On Premise où il faut, pour l'instant effectuer quelques manipulations différentes pour arriver un résultat similaire... ou presque.


Le contexte global

système d'exploitation de développement : win 7
TFS : version 2015 On Premise
Dev tools : VS 2015 ent

La solution





Le project.json du projet de test du site web asp.net core



Le project.json du projet de test du projet de classe partagé



Le project.json du projet classe partagé



Le project.json du projet web asp.net core





La build TFS


les tasks de la build


task 1





task 2




task 3




task 4


task 5




task 6



task 7



task 8



task 9




-target:dotnet.exe -oldStyle -register:user -targetargs:"test -c projectDir.Website.Tests -o $(Build.StagingDirectory)/Outputs -xml Outputs/test-results.xml" -output:Outputs/OpenCover.xml -returntargetcode -hideskipped:All -filter:"+[projectDir.*]* -[*.Tests]*" -targetdir:"projectDir.Website.Tests"




-target:dotnet.exe -oldStyle -mergeoutput -targetargs:"test -c projectDir.Shared.Tests -o $(Build.StagingDirectory)/Outputs -xml Outputs/test-results.xml" -output:Outputs/OpenCover.xml -returntargetcode -hideskipped:All -filter:"+[projectMainDir.*]* -[*.Tests]*" -register:user  -targetdir:"projectDir.Shared.Tests"



task 10



task 11



task 12




task 13




task 14




task 15


copy and publish artifact



Sortie de build





Résultats de tests





Dossier de sortie code coverage





Résultat du code coverage




Détails du code coverage par projet









Deployment avec Release Management










outils et liens utilisés :

openCover

https://github.com/opencover/opencover/releases

https://github.com/opencover/opencover/wiki/Usage

http://stackoverflow.com/questions/36460254/vs2015-code-coverage-not-working-with-tests-in-asp-net-core-1-0-formerly-known

https://blog.markvincze.com/setting-up-coveralls-for-a-net-core-project/


jeudi 3 novembre 2016

ASP.NET Core MVC AutoPostBack dropdownlist TagHelper

Si vous avez commencé à jouer avec ASP.NET Core MVC, vous avez probablement commencé à utiliser les TagHelpers, car c'est vraiment une fonctionnalité GENIALE.

La problématique


Pour le développement d'un site, j'ai dû intégrer la "Localisation" (inspiré de l'excellent article de Andrew Lock) et permettre à l'utilisateur de changer de langue sur le site.


Dans l'exemple qui suit, on est obligé de cliquer sur le bouton "OK" pour poster le formulaire de validation du choix de langue et cela n'est pas très ergonomique. Mon intention est donc de changer  la langue au moment où l'on choisit un langue dans le menu déroulant, sans trop modifier le code existant :




Le fait est que dans notre cas, j'utilise un composant "select" avec des "TagHelpers" et je ne souhaite surtout pas modifier ce composant très pratique. Comment faire donc pour avoir mon autoPostBack sur ce composant ?

Une solution possible


J'ai opté pour une solution assez simple à l'aide du bon vieux JavaScript :



J'ai rajouté une action "onchange" sur mon composant Html, suivi d'un simple "submit" de mon "form" car au final, c'est bien ce que faisait mon bouton "Ok" que je souhaitais supprimer.
Et voilà, le tour est joué.
Comme d'habitude, si vous avez des solutions alternatives et meilleurs, je suis preneur.

lundi 31 octobre 2016

Démarrer un site avec ASP.NET Core avec un code legacy en .NET classique (.NET Framework)

On arrive bientôt à la fin d'année 2016 et .NET Core est loin d'être finalisé. Cependant, on peut déjà s'aventurer sur cette nouvelle plateforme même si on a un code existant.

Configuration adaptée
Visual Studio 2015 update 3




L'idée ici est de ne surtout pas se tromper lors du choix du template ASP.NET Core : Au moment de créer votre nouveau site Asp.net MVC core, il faudra sélectionner le template ciblant le framework .NET et  non .NET Core (cf l'image ci-dessous). Cela nous vous permettra de pouvoir reférencer vos projet (dll) existants qui ne sont pas en .NET Core.



A noter également l'importance de la version cible : ici la version du framework est la 4.6.1. Il faudra donc idéalement que tous mes projets existants soit compilés sous la même version (4.6.1 donc) que mon site web, afin de pouvoir les référencer.
Dit comme ça, cela peut paraitre évident, mais vous verrez qu'au quotidien, tout un ensemble d'erreurs seront dûes aux imcompatibilités de version de framwork de vos projets existants et nouveaux.

Je crée ensuite mon application web avec le template Web Application, sachant qu'une des nouveautés intéressante avec .NET Core c'est que la partie Web API est fusionnée (au niveau des controlleurs).






Dans le fichier project.json de notre application Web Core, on voit bien que le framework cible est uniquement : net461; sachant qu'on pourrait "targeter" plusieurs frameworks dans l'absolu.



A date, le tooling ainsi que les librairies disponibles en .net Core pure ne sont pas encore finalisés.

Reférencons maintenant une librairie existante (de notre code legacy) en faisant "clique droit" sur "références" dans notre projet web, puis "Add reference...". Regardons maintenant dans notre project.json du projet web :



Notre projet "MyProjectServices" est bien reférencé sans problème. A noté que ce projet de classe cible bien le framework 4.6.1.

Projet de Test unitaires

Ajoutons un projet de tests unitaires :


A l'identique du projet ASP.NET Core, on cible bien le framework 4.6.1. Afin de pouvoir rentre compatible le projet de test au projet ASP.NET Core, on crée un projet de classe ".NET Core".
En essayant de rajouter en référence le projet web, nous obtenons le message d'erreur suivant :


C'est pour évider ce type d'erreur de référence qu'il faut être vigilant à propos des versions de framework des différents projets.

Nous allons modifier le fichier project.json du projet de classe en '"Core" que nous venons de créer afin de le rendre compatible et utilisable comme projet de tests unitaires.


Comme pour les autres projets encore une fois, nous utilisons le même framework cible "net461". On rajoute également les dépendances au framework de test XUnit et on spécifie également le "runner" associé. Une fois le "restore" de nos packages effectués, l'ajout de reférence du projet web s'effectue sans problème.


En créant un premier test unitaire de controller, on résout les dépendances sans problème, et l'exploirateur de tests reconnait bien et affiche tous nos tests.
Voilà à quoi ressemble notre project.json du projet de test au final :


En conclusion,
Nous avons donc un projet ASP.NET Core ciblant le framework 4.6.1, qui peut reférencer des librairies de classes sous le même framework, ainsi qu'un projet de test compatible pour notre projet ASP.NET Core. Nous n'avons donc pas besoin de reécrire nos librairies et packages en .NET Core grace au mécanisme précédemment utilisé. Cela nous permettra donc de nous amuser avec les nouveautés ASP.NET Core MVC pour la partie Web, utiliser nos librairies métiers et transverses existantes, tout en préparant une transition en douceur sans tout casser dans nos solution existante.


dimanche 28 février 2016

Un site web ASP.NET MVC 5 de A à Z - Le M le V et le C

Avant de rentrer dans le vif du sujet nous allons parler du model MVC et faire un tour d'horizon sur ses 3 composants à savoir :

  • le Model (model)
  • la Vue (view)
  • le Controlleur (controller)


Le MVC c'est avant tout un pattern (un design pattern à la base) orienté Web.  L'idée est d'organiser le code de façon à ce qu'il soit plus maintenable, testable, et que chaque partie soit plus ou moins autonome avec une resposabilité précise, afin de diminuer le couplage entre composant.
Il faut donc comprendre que le MVC c'est avant tout conceptuel : c'est à dire que chaque composant, selon les langages, et la façon dont on décide de l'implémenter présentera des nuances mais l'idée maitresse reste la même :

  • Le controlleur a pour mission principale d'envoyer à l'utilisateur la vue contenant une composition d'un ou plusieurs model.
  • La vue représente ce qui va être renvoyé à l'utilisateur : au niveau Web c'est le contenu Html (ou autre ressource demandé par l'utilisateur) affiché en règle générale. Les vues peuvent être organisées et divisées en vues partielles.
  • Le modèle représente les données qui seront associés et affichées au niveau des vues. On parle également de View Model pour "typer" fortement le modele à une vue précise


Même si le controlleur peut renvoyer autre chose que des vues comme par exemple du json brut, il demeurt que sont rôle principal et de préparer la vue à afficher : il consolide donc les données à partir de model(s)  servant de "gabarit" de données et via des règles métiers provenant de composants dédiés (services externes/web service, couches techniques tiers, etc).
En effet, même si on peut facilement implémenter les règles métiers au niveau du controlleur, il est plus judicieux de le faire dans un composant décorelé, afin justement de bien séparer les rôles.

Jusque là, on est au niveau théorique : dans la pratique, et plus précisement en ASP.NET MVC, c'est beaucoup plus compliqué que cela :
on a au départ une requête effectué par un utilisateur via une URL saisi dans son navigateur. Entre la résolution DNS (et toutes la partie traitement réseau que je vous épargne ici) et retour du serveur répondant web répondant à la requête, il va se passer tout un tas de choses. On parle souvent de cycle de vie ou de pipe Line de la requête.
Voici en image (trouvé sur dotnetcurry) ce qui se passe de façon macro :



Voici ce qui se passe si l'on regarde de plus près :



Les grandes étapes du traitement de la requête sont donc :

  • le routing (Routing) 
  • interception de la requete pas le module de routing 
  • execution du handler MVC
  • execution du controlleur
  • rendue de la vue
Il n'est pas obligatoire de comprendre le fonctionnement interne du cycle de vie MVC en .NET, par contre vous allez vite vous y interessé quand vous allez passer à la pratique, notamment quand vous serrez confronter à certaines problématiques de sécurité, de gestion d'url, etc. Il veux mieux donc comprendre un minimum par où passe ma requête, ce qui se passe, et comment le résultat m'est rendu.

jeudi 31 décembre 2015

Un site web ASP.NET MVC 5 de A à Z - Initiation au versionning avec Git (partie 2)

Dans notre article précédent, nous avions vu comment utiliser Git dans notre projet avec Visual Studio. Cette fois-ci nous allons voir comment mettre en place une STRATEGIE DE BRANCHES : il s'agit en réalité de mettre en place un vrai processus de gestion de branches qui s'inscrit dans une optique DevOps.


Pourquoi mettre en place une stratégie de branches ?

Pour répondre à cette questions, voici d'autres questions qui font office de réponse :

  • Comment travailler à plusieurs sur le projet sans collision ?
  • Comment je sais quelle version de mon application est en production ?
  • Comment je vois l'historique de mon application ?
  • Comment je reviens à une version précédente (rollBack) ?
  • comment je fais si j'ai un bug en Production ?
  • Comment je fais pour livrer une évolution sans embarquer celle de mon collègue ?
  • Comment je récupère les évolutions de mon collègue X sans celle de mon collègue Y ?
  • Comment je travaille proprement avec des collègues qui travaillent sur le même projet depuis un autre site ou autre pays ?


Stratégie de branches avec Git

Il existe une multitude de stratégie de branches existantes et ayant fait leur preuve. Il faut cependant admettre que chaque projet à ses spécificités et il convient d'adapter sa stratégie pour faciliter au mieux le travail des développeurs/ops/testeurs.
L'exemple ci-dessous est celui que j'utilise le plus souvent :





source : http://nvie.com/posts/a-successful-git-branching-model

L'idée de ce système de branching est de "tirer" une branche pour chaque feature (fonctionnalité à développer). En plus, des branches plus "stables" doivent exister pour gérer le cycle de vie de l'application :

  • la branche master : elle sert de versionning pure des versions livrées en prod. A chaque déploiement en production, un merge doit être fait sur cette branche depuis la branche "release" ainsi qu'une apposition de tag Git qui sert d’étiquetage de la version.
  • la branche release : c'est la branche source de livraison. Une fois les devs des features terminés, on merges toutes les features branches vers la branche develop. De la branche develop, on merge vers la branche 'release' pour une MEP à venir.
  • la branche hotfixes : comme son nom l'indique, elle sert à patcher en production. Ainsi lorsqu'un bug critique/majeur apparaît en production et que l'on souhaite le corriger sans impacter les dev en cours, on utilise cette branche. un merge est alors effectué depuis la branche.
  • la branche develop : cette branche sert de merge des branches de features développé. c'est en quelque sorte la branche mère des devs en cours. Une fois les devs des features terminés, les branches de feature sont mergées vers la branche 'develop'. Une fois les 'merges' effectués, c'est de cette branche qu'on mergera vers la branche 'release'.
  • les branches de  feature : Git propose une grande souplesse en terme de branching. Ainsi, pour chaque User Storie que vous vous attribuez en début de sprint, vous pouvez tirer une branche à partir de 'develop'. Cette branche servira de développement de votre US, que vous pourrez remerger vers 'develop' une fois le développement terminé. Il arrive souvent qu'un développeur ait besoin de partager son dev avec un autre : dans ce cas, il peut merge sa branche vers 'develop' s'il estime que son développement est assez abouti et l'autre développeur pourra récuperer les modifications merger. Avec Git, un merge pourra être fait également d'une branche de 'feature' d'un développeur vers une autre branche de 'feature'.

Dans tous les cas, vous l'aurez certainement deviné, l'aspect collaboratif reste primordial. Il convient de communiquer le plus possible avec vos collègues afin de faciliter les 'merge' et la gestion de vos branches.