Mostefai Mohammed Amine's Blog

Say That I Was Here !

Tutoriel 5.1 - Création d’un service de recrutement–Partie 1

L’objectif de ce tutoriel (cours 5) est de mettre en place un workflow de recrutement basé sur les services WCF. Pour ce, le workflow est hébergé dans une application console. Le candidat dispose d’une application qui lui permet de postuler à un poste et l’évaluateur a une application lui permettant d’évaluer une candidature. A la fin de l’évaluation, le candidat reçoit une notification de la note s’il a été accepté ou pas. Au début, si l’âge du candidat est inférieur à 30, sa candidature est systématiquement rejetée sans passer par l’évaluation. Etape 1 – Création de la solution. L’objectif est de créer une solution qui va contenir les différents modules du tutoriel. Lancez Visual Studio en tant qu’administrateur Créez une nouvelle solution vide appelée « Tutoriel51 » Ajoutez à la solution un projet de type « Application de service WCF Workflow » et appelez-le « EmbaucheLibrary » Remarquez que le projet contient un fichier dont l’extension est « xamlx » appelée « Service1.xamlx » Supprimez ce fichier Ajoutez au projet un nouvel élément de type « Service Workflow WCF » et appelez-le « EmbaucheSimpleService » Remarquez que par défaut, VS 2012 crée une séquence avec une activité « Receive » et une activité « Send » Supprimez la séquence et toutes les activités avec Etape 2 : Création d’un contrat de données L’objectif de cette étape est de créer un contrat de données (DataContract) qui représente des données qui vont être sérialisées et envoyées sur le réseau à travers les services WCF. Ajoutez une nouvelle classe au projet « EmbaucheSimpleService » appelée « CandidatInfo » Ajoutez deux propriétés publiques appelées «Nom » et « DateNaissance » de type « String » et « DateTime » public DateTime DateNaissance { get; set; } public string Nom { get; set; }   Ajoutez un « using » vers l’espace de nom « System.Runtime.Serialization » Décorez les deux propriétés avec l’attribut « DataMember » Décore la classe avec l’attriobut « DataContract » Compilez la solution pour vérifier l’absence d’erreurs. Le listing complet devrait être comme suit : [DataContract] public class CandidatInfo { [DataMember] public DateTime DateNaissance { get; set; } [DataMember] public string Nom { get; set; } }   Etape 3 : Création du service de candidature L’objectif de cette étape est de créer un service workflow qui permettra au candidat de présenter ses informations : nom et date de naissance. Ouvrez le workflow « EmbaucheSimpleService.xamlx » Glissez un organigramme sur le workflow Glissez une activité « ReceiveAndSendReply » et connectez-la au nœud de démarrage Cliquez sur l’organigramme parent Créez une variable « info » dont le type est « CandidatInfo » Créez une deuxième variable appelée « Resultat » de type « Boolean » Créez une troisième variable appelée « Note » de type « Int32 » Double-cliquez sur la séquence Renommez la première activité « Receive » en « Recevoir Candidature » Entrez « RecevoirCandidature » dans la zone « Nom de l’opération » Dans la propriété « ServiceContractName », entrez « IEmbaucheService » Cochez la propriété « CanCreateInstance » Cliquez sur « Contenu », la boîte de dialogue ci-dessous devrait apparaître Cliquez sur le bouton radio « Paramètres » Cliquez sur « Ajoutez nouveau paramètre » Dans la zone « Nom », entrez « pInfo » Pour le type, sélectionnez « CandidatInfo » Dans la zone « Assign To », entrez « info » Cliquez sur OK Glissez une activité de type « Assign » entre l’activité « Receive » et l’activité « Send » Dans la zone « To », entrez « Resultat » Dans la zone « Value » entrez l’expression suivante :info.DateNaissance < DateTime.Today.AddYears(-30) Ajoutez une activité « WriteLine » après « Assign » et avant « SendReplyToReceive » Affectez l’expression suivante à la propriété « Text »string.Format("Candidature reçue, nom : {0}, dn : {1}",info.Nom,info.DateNaissance) Dans l’activité « SendReplyToReceive », cliquez sur « Contenu » Dans la liste déroulante « Message Type », sélectionnez « Boolean » Dans la zone « Message Data », entrez « Resultat » La séquence devrait être comme suit : Compilez pour vérifier la présence d’erreurs. Etape 4 : Test du service L’objectif de cette étape est de tester le service en utilisant l’outil « WCFTestClient » fourni avec Visual Studio. Dans Visual Studio, dans l’explorateur de solution, cliquez avec le bouton droit sur le fichier « EmbaucheSimpleService.xamlx » Cliquez sur « Afficher sur le navigateur » Remarquez la définition du service s’affichant dans le navigateur.   Copiez l’adresse du service à partir de la barre d’adresse Lancez l’explorateur Windows Allez sur le répertoire d’installation de Visual Studio Allez sur le répertoire « Common7 à IDE » Exécutez l’outil « WCFTestClient.exe » Cliquez « Fichier à Ajouter Service » Dans la boîte de dialogue qui apparait, dans la zone de texte, collez l’URL copiée lors de l’étape 4 Remarquez la présence du service « IEmbaucheService » avec la méthode « RecevoirCandidature » Double-cliquez sur « RecevoirCandidature » Affectez des valeurs au paramètre « pInfo » (utiliser l’assistant qui propose des valeurs par défaut) Cliquez sur « Invoke » Remarquez que le service renvoie « True » pour les dates de naissance de plus de 30 ans et false sinon Etape 5 : Création de l’application d’hébergement en mode console Une des nombreuses façons d’héberger un workflow de service est une application de console. L’objectif de cette étape est d’utiliser la classe « WorkflowServiceHost » pour héberger un workflow. Ajoutez à la solution un nouveau projet de type « Application Console Workflow » et appelez-la « ConsoleWorkflowHost » A partir de l’explorateur de solution, faites de ce projet le projet de démarrage A partir de l’explorateur de solution, supprimer le workflow « Workflow1.xaml » créé avec le projet Ajoutez une référence vers « EmbaucheLibrary » Ouvrez le fichier « Program.cs » Supprimez le contenu de la méthode « Main » Ajoutez un using vers « System.ServiceModel.Activities » Ajoutez un using vers « System.Xaml » Ajoutez un using vers « System.ServiceModel.Description » La première étape consiste à charger le service à partir du fichier :// charger le service à partir du fichier WorkflowService service = XamlServices.Load(@"F:\FormationWF\Tutoriaux\Chapitre 5\Tutoriel51\EmbaucheLibrary\EmbaucheSimpleService.xamlx") as WorkflowService; Remplacez le chemin indiqué par le chemin dans lequel se trouve votre code source La deuxième étape consiste à compiler le service :// compiler le service Compile(service); Nous fournirons l’implémentation de la méthode « Compile » dans une prochaine étape La prochaine étape consiste à définir l’adresse du service :// définir l'adresse du service Uri address = new Uri("http://localhost:9988/EmbaucheSimple"); Ensuite, nous lancerons l’hôte en utilisant le workflow et l’adresse :// créer le hôte WorkflowServiceHost host = new WorkflowServiceHost(service, address); Nous paramétrerons le service de façon à ce qu’il communique ses métadonnées via HTTP :// communiquer métadonnées via HTTP host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true }); Nous supprimerons ensuite le comportement de débogage du service// supprimer le comportement de débogage host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior)); Nous ajouterons ensuite le comportement qui inclut les informations des exceptions avec les messages. Ce comportement est très utile pour le débogage.// inclure les détails des exception dans les messages host.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true }); Maintenant que l’hôte est configué, il faut le lancer// démarrer le service host.Open(); Ajoutons une instruction qui lit une touche à partir du clavier (Console.ReadKey()) et afficher un message avantConsole.WriteLine("Service démarré"); Console.ReadKey(); Le listing complet de la méthode « Main » devraît être comme suit : static void Main(string[] args) { // charger le service à partir du fichier WorkflowService service = XamlServices.Load(@"F:\FormationWF\Tutoriaux\Chapitre 5\Tutoriel51\EmbaucheLibrary\EmbaucheSimpleService.xamlx") as WorkflowService; // compiler le service Compile(service); // définir l'adresse du service Uri address = new Uri("http://localhost:9988/EmbaucheSimple"); // créer le hôte WorkflowServiceHost host = new WorkflowServiceHost(service, address); // communiquer métadonnées via HTTP host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true }); // supprimer le comportement de débogage host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior)); // inclure les détails des exception dans les messages host.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true }); // démarrer le service host.Open(); Console.WriteLine("Service démarré"); Console.ReadKey(); } Ajoutez un using vers « System.Activities.XamlIntegration » Ajoutez un using vers « System.Activities.Expressions » Ajoutez la méthode « Compile » comme suit : static void Compile(WorkflowService workflowService) { TextExpressionCompilerSettings settings = new TextExpressionCompilerSettings { Activity = workflowService.Body, Language = "C#", ActivityName = workflowService.Name + "_CompiledExpressionRoot", ActivityNamespace = string.Join(".", "CompiledExpressions"), RootNamespace = null, GenerateAsPartialClass = false, ForImplementation = false, // Important tip - ForImplementation should only be true when compiling an ActivityBuilder, it must be false when compiling an Activity such as a WorfkflowService body. };  TextExpressionCompilerResults results = new TextExpressionCompiler(settings).Compile();  if (results.HasErrors) { throw new Exception("Compilation failed."); }  ICompiledExpressionRoot compiledExpressionRoot = Activator.CreateInstance(results.ResultType, new object[] { workflowService.Body }) as ICompiledExpressionRoot;  CompiledExpressionInvoker.SetCompiledExpressionRoot( workflowService.Body, compiledExpressionRoot); }   L’implémentation de « Compile a été tirée du service de « Microsoft » (https://connect.microsoft.com/VisualStudio/feedback/details/743870/workflow-foundation-4-5-workflowservicehost-xamlx-expression-activity-type-csharpvalue1-requires-compilation-in-order-to-run ) Etape 6 : Création du service d’évaluation L’objectif de cette étape est d’ajouter le service permettant à la commission technique d’évaluer un candidat. Ouvrez le workflow « EmbaucheSimpleService.xaml » Ouvrez l’organigramme principal qui contient la séquence Ajoutez une activité « FlowDecision » et connectez-la à la séquence Entrez « Resultat » dans l’expression de la condition de la décision Ajoutez une activité « Receive » et appelez-la « Recevoir Evaluation » Connectez l’activité au label « True » de la décision Entrez « IEmbaucheService » dans la propriété « ServiceContractName » Entrez « Evaluer » dans la zone « Nom de l’opération » Cliquez sur le bouton « Contenu » de l’activité « Receive » Cliquez sur le bouton radio « Paramètres » Ajoutez un paramètre appelé « nom » de type « String » Ajoutez un paramètre appelé « note » de type « Int32 » affectée à la variable « Note » Cliquez sur « OK » Ajoutez une activité « Assign » et connectez-la au dernier « Receive » Dans la zone « To » entrez « Resultat » Dans la zone expression, entrez « Note >=3) Le workflow devrait être comme suit : Compilez pour vérifier les erreurs. Vous pouvez accéder à la suite du tutoriel ici.

WCF et IIS 8.5, Régler le problème de l’erreur 404.17

Après quelques recherches internet et bien sûr, des maux de tête, j’ai réussi à débloquer le problème d’erreur 404.17 faisant suite à l’hébergement d’un service WCF sur IIS 8.5. Sachant que j’utilise IIS 8.5 sous Windows 8.1, la solution est relativement simple : Lancer le panneau de configuration Lancer “Programmes et Fonctionnalités” Activer ou Désactiver des Fonctionnalités Windows” Services .NET Framewok 4.5 avancé Service WCF Activation HTTP                   Le problème devrait être logiquement résolu