Procédure pas à pas : Développement d’applications PSI à l’aide de WCF (traduction automatique)

Dernière modification : lundi 30 mai 2011

S’applique à : Office 2010 | Project 2010 | Project Server 2010 | SharePoint Server 2010

Dans cet article
Création d'une Application Console pour WCF
Ajout de références de Service
Programmation avec la PSI
À l'aide du Service Queuing de Project Server
Exemple de Code complet

Important

Cet article a été traduit automatiquement, voir l’avertissement. Vous pouvez consulter la version en anglais de cet article ici.

Microsoft Project Server 2010 utilise WCF (Windows Communication Foundation) pour accéder aux interfaces des services WCF et des services Web ASMX de l’interface PSI. Cet article montre comment développer une application WCF pour Project Server et comment utiliser le service de mise en file d’attente de Project Server. Vous pouvez créer les liaisons et les points de terminaison WCF entièrement dans le code ou bien utiliser l’éditeur de configuration de service WCF pour modifier le fichier app.config pour l’application. L’utilisation d’un fichier app.config permet la reconfiguration de l’application sans recompilation, par exemple pour changer le protocole de transport de HTTP en TCP/IP direct. (L’exemple de code de cet article est une adaptation d’une application de test conçue par Tiger Wang, Microsoft Corporation.)

Le présent article contient les sections suivantes :

  • Création d'une Application Console pour WCF

  • Ajout de références de Service

    • Configuration des Services par programme

    • Configuration des Services avec app.config

  • Programmation avec la PSI

  • À l'aide du Service Queuing de Project Server

  • Exemple de Code complet

Pour une introduction aux concepts de développement d'applications de Project Server à l'aide de WCF, consultez Vue d’ensemble de WCF et de l’interface PSI (traduction automatique). Pour les procédures générales à utiliser dans le développement, y compris des conseils sur la définition de descriptions Intellisense pour la PSI et sur les trois façons d'ajouter une référence de service, consultez Conditions préalables pour les exemples de code basés sur WCF (traduction automatique). Voir aussi Beginner's Guide to Windows Communication Foundation.

Le téléchargement du Kit de développement logiciel de Project 2010 inclut deux projets de Microsoft Visual Studio pour l'application WCFHelloProject.

  • Le répertoire WCFHelloProject_Prog dans le téléchargement est le projet de configuration par programme des points de terminaison, à l'aide de Microsoft Visual Studio 2008 SP1. La solution n'utilise pas un fichier app.config. Les références aux services de projet et QueueSystem sont définies directement dans Visual Studio.

    Avertissement

    Comme expliqué dans Conditions préalables pour les exemples de code basés sur WCF (traduction automatique), directement en définissant une référence de service dans les versions postérieures à la bêta de Project Server 2010 requiert temporairement remplacer le fichier web.config de l'application de service de Project Server. Nous recommandons l'utilisation d'un assembly de proxy pour les services PSI ou ajout d'un fichier de code source proxy pour chaque service qu'utilise l'application. Les fichiers de code source de proxy sont créés lorsque vous exécutez le script pour créer l'assembly de proxy. Le Kit de développement Project 2010 inclut les fichiers de code source de proxy.

  • Le répertoire WCFHelloProject_vs10_CfgEd utilise Microsoft Visual Studio 2010 et un fichier app.config. Les références aux services de projet et QueueSystem utilisent wcf.Project.cs et wcfQueueSystem.cs proxy fichiers de code source créés par la commande SvcUtil.exe dans le script qui crée l'assembly de proxy PSI.

Conditions préalables requises

Développement d'applications WCF nécessite Microsoft Visual Studio 2008 SP1 ou Visual Studio 2010. Les applications doivent cibler Microsoft.NET Framework 3.5. Les procédures décrites dans cet article utilisent Microsoft Visual c#.

Pour les applications de Project Server, ciblez le.NET Framework 3.5 à la place de la.NET Framework 3.5 Client Profile, sauf si vous incluez également une solution de sandbox de client pour Microsoft SharePoint Server 2010. Pour plus d'informations sur le développement de clients de SharePoint, consultez What's New: Client Object Model dans le SDK SharePoint Foundation 2010.

Étapes des procédures utilisent Visual Studio s'exécutant sur un test d'installation d'un ordinateur de Project Server.

Avertissement

Vous devez développer des applications de serveur de projet sur une installation de test, plutôt que sur une installation de production, de Project Server.

Notes

Lorsque vous exécutez l'application sur un ordinateur distinct, vous devez installer Microsoft.Office.Project.Server.Library.dll avec l'application. Le téléchargement du Kit de développement logiciel de Project Server 2010 inclut une licence de redistribution de l'assembly Microsoft.Office.Project.Server.Library.dll.

Authentification basée sur les revendications   Tous les types d'authentification des applications basées sur la plate-forme SharePoint 2010 sont basés sur des créances. L'exemple de WCFHelloProject est conçu pour une installation de Project Server qui utilise uniquement l'authentification Windows. Si Project Server est configuré pour multi-authentication (Windows et authentification par formulaires), tous les appels aux méthodes PSI doivent figurer dans une section de OperationContextScope, qui ajoute un en-tête à la demande Web sortant qui bloque l'authentification basée sur les formulaires. Pour plus d'informations, consultez Conditions préalables pour les exemples de code basés sur WCF (traduction automatique).

Création d'une Application Console pour WCF

L'application de console WCFHelloProject est un exemple qui peut être réutilisé pour tester des applications simples de Project Server. Code de la Main méthode, la méthode ParseCommandLine et la méthode Usage peuvent être adaptées pour une grande variété d'applications.

Procédure 1. Pour créer une application de console WCF pour la PSI

  1. Exécutez Visual Studio en tant qu'administrateur et puis créer une application console. Par exemple, nommez l'application WCFHelloProject. Dans la liste déroulante en haut de la boîte de dialogue Nouveau projet , sélectionnez .NET Framework 3.5 que le cadre cible.

  2. Ajoutez les références suivantes :

    • System.Runtime.Serialization est utilisé dans le code de proxy de service WCF (Reference.cs) qui est généré lorsque vous définissez une référence de service.

    • System.ServiceModel est requis pour la configuration des services WCF. Pour une application Web, vous devez également System.ServiceModel.Web. Si vous ajoutez des services Web ASMX, vous devez System.Web.Services.

    • Microsoft.Office.Project.Server.Library se trouve dans l'assembly [Program Files]\Microsoft Office Servers\14.0\Bin\Microsoft.Office.Project.Server.Library.dll. Si l'application utilise les événements de Project Server, vous devez également ajouter une référence à l'assembly Microsoft.Office.Project.Server.Events.Receivers.dll dans le même répertoire.

  3. Dans le fichier Program.cs, ajoutez les variables suivantes de la classe Program. Les deux dernières variables sont spécifiques à l'application WCFHelloProject.

    static private Uri pwaUri;          // URI of Project Web App.
    static private string pwaUrl;       // URL of Project Web App.
    static private string argError;     // Contains the argument that is in error.
    
    static private int numProjects;     // Number of projects to create.
    static private bool deleteProjects; // Specifies whether to delete projects.
    
  4. Créez la méthode ParseCommandLine, qui analyse la ligne de commande et définit des argError s'il existe une erreur d'argument. Pour l'exemple de code de toutes les méthodes dans le fichier Program.cs, consultez l' Exemple de Code complet.

  5. Créez la méthode Usage, qui affiche l'utilisation de la commande.

  6. Dans la méthode Main, initialisez les variables de classe. Une fois que vous écrivez la classe CreateProjects (procédure 2), ajoutez le code qui s'exécute lorsque la méthode ParseCommandLine renvoie true.

    static void Main(string[] args)
    {
        pwaUrl = string.Empty;
        pwaUri = null;
        numProjects = 2;
        deleteProjects = true;
        argError = null;
    
        if (args.Length == 0)
        {
            Usage(argError);
        }
        else if (ParseCommandLine(args))
        {
            // TODO: Add code to instantiate the CreateProjects class and run its methods.
        }
        else
        {
            Usage(argError);
        }
        // Keep the Command Prompt window open for debugging.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey(true);
    }
    

Vous pouvez ajouter des classes pour le reste de l'application dans le fichier Program.cs, mais il est plus facile de réutilisation du code créer des fichiers de classe distinct pour la partie principale de l'application.

Ajout de références de Service

Pour utiliser l'interface de WCF de la PSI, vous devez ajouter et configurer les références de service. La procédure 2 montre comment ajouter les références de service. Procédure 3 montre comment configurer les services par programme, ou vous pouvez éventuellement utiliser 4 de la procédure pour configurer les services à l'aide d'un fichier app.config.

Espaces de noms que vous donnez aux références de service sont arbitraires, mais elle aide à maintenir une convention d'appellation de service WCF et les références de service Web ASMX. Par exemple, le Kit de développement Project 2010 utilise généralement Svc [NomService] pour les services WCF (tel que SvcProject). Le fichier de Visual Studio Intellisense (ProjectServerServices.xml) dans le téléchargement du Kit de développement de l'assembly de proxy PSI utilise également le préfixe de Svc .

Conseil

Cet article explique comment ajouter des références de service directement dans Visual Studio. Sinon, nous vous recommandons d'utiliser l'assembly de proxy ProjectServerServices.dll dans le téléchargement du Kit de développement logiciel Project 2010 et de définir une référence à cet assembly. L'article Conditions préalables pour les exemples de code basés sur WCF (traduction automatique) comprend des instructions détaillées pour la création d'une référence de service, ainsi que des instructions pour l'assembly de proxy et l'utilisation de fichiers de code source de proxy. Un des avantages de la définition d'une référence à l'assembly de proxy ProjectServerServices.dll sont que vous pouvez utiliser le fichier ProjectServerServices.xml dans le même répertoire afin qu'Intellisense affiche type et membre de descriptions.

Procédure 2. Pour ajouter des références de service WCF

  1. Remplacer temporairement le fichier web.config dans le répertoire virtuel du Service de projet principal, comme décrit dans Procédure : Créer un assembly de proxy pour des services WCF (traduction automatique). Exécutez iisreset.

  2. Dans l'Explorateur de solutions Visual Studio, cliquez droit sur le nœud Références et puis cliquez sur Ajouter une référence de Service. Dans le champ Adresse de la boîte de dialogue Ajouter une référence de Service , tapez ou collez l'URL du service PSI dont vous avez besoin. Pour le service de projet, collez le texte suivant :

    https://localhost:32843/[GUID]/PSI/Project.svc
    

    Le GUID est le nom du répertoire virtuel Services Project Server dans l'application Web de SharePoint Services (voir le Gestionnaire des services Internet (IIS)). Le nom du répertoire virtuel est également l'ID de l'application de Service de Project Server dans SharePoint. Pour plus d'informations sur l'URL du service, reportez-vous à l'aide de la WCF et les Interfaces ASMX section au Vue d’ensemble de WCF et de l’interface PSI (traduction automatique).

    Conseil

    Pour trouver rapidement le GUID de l'application de Service de Project Server, utilisez une commande Windows PowerShell qui est installée avec SharePoint Server 2010. Dans le menu Démarrer , cliquez sur Tous les programmeset cliquez sur Produits Microsoft SharePoint 2010, Environnement de gestion SharePoint 2010. Voici les commandes et les résultats (votre GUID seront différent).

    PS> $serviceName = "Project Server Service Application"

    PS> get-SPServiceApplication -name $serviceName | select Name, Id

    Name                                    Id

    Project Server Service Application      51125047-6279-4ae8-890a-b67a5daec75e

    Le nom du répertoire est 5112504762794ae8890ab67a5daec75e (sans les tirets).

  3. Tapez le nom de l'espace de noms de service de projet. Par exemple, tapez SvcProjectet cliquez sur OK (Figure 1).

    La figure 1. Ajout d'une référence de service WCF

    Ajout d’une référence au service WCF

    Lorsque vous ajoutez une référence de service, Visual Studio ajoute également un fichier app.config contenant deux liaisons par défaut et les points de terminaison du service. Vous pouvez exclure ou supprimer le fichier app.config si vous utilisez exclusivement pour WCF et configurez les services par programme (procédure 3), ou vous pouvez modifier le fichier app.config à l'aide de l'éditeur de Configuration de Service WCF (procédure 4).

  4. De même, ajoutez une référence au service de QueueSystem et nommez-le SvcQueueSystem.

  5. Avant de configurer les services, ajoutez un fichier de classe pour le code de l'application principale pour le projet WCFHelloProject dans Visual Studio. Par exemple, dans la boîte de dialogue Ajouter un nouvel élément – WCFHelloProject , cliquez sur l'élément de Classe objet et nommez le fichier CreateProjects.cs. Visual Studio ajoute la classe CreateProjects.

  6. Ajoutez les instructions de using suivant les instructions par défaut dans le fichier CreateProjects.cs. L'alias d'espace de noms backendProject et l'alias d'espace de noms backendQueueSystem sont facultatifs. Il s'agit d'un rappel dans l'exemple de WCFHelloProject les références de service QueueSystem et de projet pour les services de Project Server (principal) locales et ne peut pas être directement accessibles à partir d'un ordinateur externe.

    using System.Net;
    using System.Security.Principal; // Required for the TokenImpersonationLevel enumeration.
    using System.ServiceModel;
    
    using PSLibrary = Microsoft.Office.Project.Server.Library;
    using backendProject = WCFHelloProject.SvcProject;
    using backendQueueSystem = WCFHelloProject.SvcQueueSystem;
    

    Au lieu de définir des références directes aux services QueueSystem et de projet, si vous utilisez l'assembly de proxy PSI ou ajoutez les fichiers de code source du proxy, les espaces de noms de service ne sont pas des enfants de l'espace de noms WCFHelloProject. Par exemple, les instructions suivantes valeur alias pour les espaces de noms dans le proxy fichiers source :

    using backendProject = SvcProject;          // The wcfProject.cs file contains the SvcProject namespace.
    using backendQueueSystem = SvcQueueSystem;  // The wcf.QueueSystem.cs file contains the SvcQueueSystem namespace.
    
  7. Ajouter des variables de classe pour les données que le constructeur initialise, afin que les données sont accessibles à toutes les méthodes dans la classe. Dans la procédure 3 ou 4 de la procédure, vous définissez la variable projectClient et la variable queueSystemClient à l'adresse de point de terminaison du routeur ProjectServer.svc (public) frontaux dans Project Web App, pour permettre l'accès aux références de service principaux PSI.

    private static backendProject.ProjectClient projectClient;
    private static backendQueueSystem.QueueSystemClient queueSystemClient;
    private static string pwaUrl;
    private static int numProjects;
    private static bool deleteProjects;
    

    Notez que Intellisense affiche ProjectClient et d'autres interfaces et classes dans la variable backendProject (qui pointe vers le service de projet principal).

    Notes

    Les classes de clients tels que ProjectClient n'existent que dans l'interface WCF. Si vous ajoutez une référence ASMX frontale vers le service Web de projet ou définissez une référence à l'assembly ProjectServerServices.dll qui est généré avec le script GenASMXProxyAssembly.cmd dans le téléchargement du Kit de développement logiciel, ou ajouter un fichier de code source proxy telles que wsdl.Project.cs, la classe ProjectClient n'est pas présente.

  8. Ajouter un constructeur pour initialiser la classe CreateProjects et procédé pour configurer les références de service. Le constructeur de classe CreateProjects utilise le paramètre Uri pour l'URI Project Web App, pour permettre l'accès par programme à toutes les parties de l'URL. Le paramètre num est le nombre de projets pour créer et le paramètre delete Spécifie s'il faut supprimer les projets après leur création.

    public CreateProjects(Uri uri, int num, bool delete)
    {
        numProjects = num;
        deleteProjects = delete;
    
        SetClientEndpoints(uri);
    }
    
    private static void SetClientEndpoints(Uri pwaUri)
    {
    }
    
  9. Lorsque vous avez fini de définir les références de service, remplacez le fichier web.config d'origine dans le répertoire virtuel du Service de projet principal, comme décrit dans Procédure : Créer un assembly de proxy pour des services WCF (traduction automatique). Exécutez iisreset.

Vous pouvez utiliser la procédure 3 ou 4 de la procédure pour ajouter du code à la méthode SetClientEndpoints et de configurer les services.

Configuration des Services par programme

Un avantage de la configuration par programmation des services WCF est qu'il est généralement plus rapide et plus facile de coller un exemple de code dans la méthode SetClientEndpoints lorsque vous apprenez à utiliser WCF. Configuration par programmation peut également servir lors de la création d'une application qui modifie le ruban Project Web App, où le fichier app.config ne doit pas être modifié, comme décrit dans Procédure pas à pas : Personnalisation du ruban PWA et accès au JS Grid (traduction automatique). Une autre fonctionnalité de configuration par programme (s'il est un avantage dépend des exigences d'application) est qu'il ne peut pas être changé, sauf si vous modifiez et recompilez l'application.

Si vous avez besoin modifier ou ajouter des mécanismes de transport, les paramètres de sécurité, des délais d'attente et autres paramètres de l'application sans recompilation, il est préférable d'utiliser le fichier app.config (procédure 4).

Procédure 3. Pour configurer les services WCF par programme

  1. S'il est utilisé uniquement pour la configuration de WCF, excluez le fichier app.config créé par Visual Studio lorsque vous définissez des références aux services PSI.

  2. Pour créer une liaison pour le client de points de terminaison, ajoutez le code suivant à la méthode SetClientEndpoints.

     const int MAXSIZE = 500000000;
    
    // Set the final part of the URL address of the 
    // front-end ProjectServer.svc router.
    const string svcRouter = "_vti_bin/PSI/ProjectServer.svc";
    
    pwaUrl = pwaUri.Scheme + Uri.SchemeDelimiter + pwaUri.Host + ":"
        + pwaUri.Port + pwaUri.AbsolutePath;
    Console.WriteLine("URL: {0}", pwaUrl);
    
    // Create a basic binding that can be used for HTTP or HTTPS.
    BasicHttpBinding binding = null;
    
    if (pwaUri.Scheme.Equals(Uri.UriSchemeHttps))
    {
        // Initialize the HTTPS binding.
        binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
    }
    else
    {
        // Initialize the HTTP binding.
        binding = new BasicHttpBinding(
            BasicHttpSecurityMode.TransportCredentialOnly);
    }
    
  3. Définissez les propriétés de la liaison pour activer l'utilisation par l'application PSI. La propriété SendTimeout doit être un intervalle de temps suffisamment grande pour gérer la latence de l'accès au serveur Project Server. La propriété de la taille maximale des messages et la propriété count de nom table caractère doivent être suffisamment grandes pour gérer les très grands ensembles de données de Project Server. La propriété MessageEncoding doit être définie pour les données texte et la propriété ClientCredentialType doit être définie pour les informations d'identification NTLM.

    binding.Name = "basicHttpConf";
    binding.SendTimeout = TimeSpan.MaxValue;
    binding.MaxReceivedMessageSize = MAXSIZE;
    binding.ReaderQuotas.MaxNameTableCharCount = MAXSIZE;
    binding.MessageEncoding = WSMessageEncoding.Text;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
    
  4. Créer une adresse de point de terminaison qui pointe vers le routeur ProjectService.svc frontaux dans Project Web App. Enfin, initialiser chacune des variables client avec la liaison WCF et l'adresse de point de terminaison. La fabrique de canaux inclut la sécurité et autres propriétés du mécanisme de transport sous-jacent du modèle de service WCF.

    // The endpoint address is the ProjectServer.svc router for all public PSI calls.
    EndpointAddress address = new EndpointAddress(pwaUrl + svcRouter);
    
    projectClient = new backendProject.ProjectClient(binding, address);
    projectClient.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel
        = TokenImpersonationLevel.Impersonation;
    projectClient.ChannelFactory.Credentials.Windows.AllowNtlm = true;
    
    queueSystemClient = new backendQueueSystem.QueueSystemClient(binding, address);
    queueSystemClient.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel
        = TokenImpersonationLevel.Impersonation;
    queueSystemClient.ChannelFactory.Credentials.Windows.AllowNtlm = true;
    
  5. Ajoutez le code dans la méthode Program.Main pour initialiser l'objet CreateProjects. Laissez les appels à la méthode Create et la méthode DisposeClients commenté, jusqu'à ce que vous écrivez de ces méthodes.

    . . .
    else if (ParseCommandLine(args))
    {
        // The command is valid, so instantiate the CreateProjects object.
        CreateProjects projectCreator = 
            new CreateProjects(pwaUri, numProjects, deleteProjects);
    
        //projectCreator.Create();
        //projectCreator.DisposeClients();
    }
    . . .
    
  6. Testez l'application, pour déterminer si l'objet CreateProjects est initialisée correctement :

    1. Dans le volet Propriétés de WCFHelloProject , cliquez sur l'onglet Déboguer et la zone de texte arguments de ligne de commande (en supposant que votre instance de Project Web App est nommé pwa) puis ajouter le texte suivant : -pwaUrl https://localhost/pwa

    2. Définissez un point d'arrêt sur le crochet fermant ("}") de la méthode de SetClientEndpoints et puis sur Exécuter l'application.

    3. Vérifiez les valeurs de certains paramètres de WCF. Par exemple, vérifiez la valeur de projectClient.ChannelFactory. Il doit être : {System.ServiceModel.ChannelFactory<WCFHelloProject.SvcProject.Project>}.

    4. Vérifiez la valeur de projectClient.Endpoint. Il doit être : Address={https://localhost/pwa/_vti_bin/PSI/ProjectServer.svc}.

    5. Lorsque vous étape à la fin de l'application, la fenêtre d'invite de commande affiche les informations suivantes :

      URL: https://localhost:80/pwa/
      Press any key to exit.
      

Configuration des Services avec app.config

L'un des avantages de la configuration des services WCF à l'aide d'un fichier app.config ou web.config sont que vous pouvez modifier les liaisons de point de terminaison sans recompiler l'application. Par exemple, vous pouvez modifier le transport à partir de HTTP pour TCP. Un autre avantage est que vous pouvez utiliser l'éditeur de Configuration du Service WCF pour ajouter ou modifier les liaisons et les points de terminaison. L'inconvénient de l'utilisation de app.config et l'éditeur de Configuration du Service WCF est qu'il existe de nombreux paramètres pour en savoir plus pour que la liaison fonctionne correctement avec Project Server.

Les liaisons par défaut et les points de terminaison Visual Studio crée dans le fichier app.config ne fonctionnent pas avec Project Server. Procédure 4 montre comment créer de nouvelles liaisons et les points de terminaison, plutôt que de modifier les paramètres par défaut.

Procédure 4. Pour configurer les services WCF avec app.config

  1. Fermez la solution WCFHelloProject dans Visual Studio, copiez le répertoire WCFHelloProject vers un autre emplacement et puis ouvrez le fichier WCFHelloProject.sln dans le nouvel emplacement.

  2. Si vous avez exclu le fichier app.config du projet, ajoutez-la dans. Droit sur le projet WCFHelloProject dans l'Explorateur de solutions, cliquez sur Ajouter, cliquez sur Un élément existantet puis naviguez vers le fichier app.config dans le nouvel emplacement du projet.

    Si vous avez supprimé le fichier app.config dans la procédure 3, au lieu de simplement à l'exclusion du projet, créez un fichier app.config. Si vous avez utilisé l'assembly de proxy ProjectServerServices.dll ou wcf.Project.cs et wcf.Pour télécharger les fichiers QueueSystem.cs dans le SDK Project 2010, vous devez également créer un fichier app.config. Pour plus d'informations sur la création d'un fichier app.config, voir la rubrique l'ajout une section du fichier de Configuration de Service dans Conditions préalables pour les exemples de code basés sur WCF (traduction automatique).

  3. Dans Visual Studio, dans le menu Outils , cliquez sur Éditeur de Configuration du Service WCF. Dans la fenêtre d'application de Microsoft Service Configuration Editor , dans le menu Fichier , cliquez sur Ouvrir, cliquez sur le Fichier de configurationet puis naviguez vers le fichier app.config pour la solution.

    Conseil

    Après avoir ouvert le fichier app.config de la première fois, vous pouvez cliquez droit sur le fichier dans l'Explorateur de solutions et puis cliquez sur Modifier la Configuration de WCF.

    Si Microsoft Service Configuration Editor affiche une erreur telle que « Attribut non reconnu 'decompressionEnabled' … », cliquez sur OKet modifiez le fichier app.config dans Visual Studio pour supprimer l'attribut non pris en charge dans tous les emplacements. Enregistrer app.config et redémarrez Microsoft Service Configuration Editor.

    Lorsque vous définissez directement une référence de service, Visual Studio crée deux liaisons par défaut pour chaque service WCF dans votre application (Figure 2). Visual Studio crée également deux points de terminaison par défaut pour chaque service, et ces points de terminaison utilisent les liaisons par défaut. Par exemple, le point de terminaison CustomBinding_Project utilise le protocole HTTPS et le point de terminaison CustomBinding_Project1 utilise le fichier NET.Protocole TCP.

    La figure 2. Les points de terminaison par défaut et les liaisons dans app.config, à l'aide de Visual Studio 2010 avec.NET Framework 3.5

    Liaisons et points de terminaison par défaut dans app.config

  4. Dans la fenêtre de l'Éditeur de Configuration du Service Microsoft , dans le volet de Configuration , avec le bouton droit de liaisonset puis cliquez sur Nouvelle Configuration de liaison. Dans la boîte de dialogue créer une nouvelle liaison , cliquez sur basicHttpBindinget puis cliquez sur OK. Renommez la liaison dans le volet basicHttpBinding . Par exemple, tapez basicHttpConf dans la zone de texte Nom .

    Modifier les propriétés générales dans l'onglet Binding , comme dans le tableau 1.

    Tableau 1. Propriétés de liaison

    propriété

    valeur

    Commentaires

    MaxBufferSize

    500000000

    MaxReceivedMessageSize

    500000000

    SendTimeout

    4775807 est au maximum possible. Essayez de 01 : 00 : 00.

    La grande valeur correspond à la propriété TimeSpan.MaxValue, qui est 10675199 jours, 2 heures, 48 minutes et environ 5 secondes — qui est supérieure à 29,000 ans. Vous pouvez réduire la valeur, par exemple, pour une plus raisonnable 01 : 00 : 00 (une heure).

    MaxArrayLength

    16384

    MaxBytesPerRead

    4096

    MaxDepth

    32

    MaxNameTableCharCount

    500000000

    MaxStringContentLength

    8192

  5. Dans le volet basicHttpBinding , cliquez sur l'onglet Sécurité et modifiez les valeurs de propriété dans le tableau 2.

    Tableau 2. Propriétés de sécurité

    propriété

    valeur

    Commentaires

    Mode

    TransportCredentialOnly

    Le mode TransportCredentialOnly transmet les informations d'identification utilisateur sans crypter ou signer les messages. Si l'URI Realm utilise le protocole HTTPS, définissez l'attribut Mode à Transport. Pour plus d'informations, consultez Programming WCF Security.

    Realm

    [http://SecurityDomain]

    Domaine de la sécurité, tels que https://www.microsoft.com/fr-fr/default.aspx. La valeur par défaut est une chaîne vide. Pour plus d'informations, consultez Claims-Based Architectures.

    TransportClientCredentialType

    NTLM

    Pour plus d'informations sur les liaisons de la sécurité, consultez Transport Security Overview.

  6. Dans le volet de Configuration , développez le nœud Avancé , cliquez sur Les comportements de point de terminaisonet puis cliquez sur Nouvelle Configuration de comportement de point de terminaison. Dans le volet de Comportement , modifiez le champ Nom de basicHttpBehavior.

  7. Dans la comportement : basicHttpBehavior volet, cliquez sur Ajouter. Dans la boîte de dialogue Ajout de Sections d'Extension d'élément de comportement , cliquez sur clientCredentialset puis cliquez sur Ajouter.

  8. Dans le volet de Configuration , sous basicHttpBehavior, cliquez sur le nœud enfant clientCredentials et modifiez la AllowedImpersonationLevelEmprunt d’identité. Laissez les valeurs par défaut pour les autres propriétés (SupportInteractive = True, ImpersonationLevel = Identification et AllowNtlm = True). Laisser les nœuds enfants sous clientCredentials avec les valeurs par défaut.

  9. Créer un point de terminaison utilise basicHttpBinding, pour chaque service WCF dans l'application.

    4 A de procédure. Pour créer des points de terminaison client

    1. Dans le volet de Configuration , cliquez sur le nœud de points de terminaison et puis cliquez sur Nouveau point de terminaison Client. Dans le volet de Point de terminaison Client , tapez un nom pour le point de terminaison ; par exemple, tapez basicHttp_Project pour le service du projet.

    2. Dans le champ Adresse , tapez l'URL du routeur ProjectServer.svc dans Project Web App, par exemple, https://ServerName/ProjectServerName/_vti_bin/PSI/ProjectServer.svc.

    3. Dans le champ de paramètre BehaviorConfiguration , dans la liste déroulante, sélectionnez le nom du comportement de point de terminaison personnalisé que vous avez créé précédemment. Par exemple, sélectionnez basicHttpBehavior.

    4. Dans le champ de Binding , sélectionnez le type de liaison. Dans ce cas, sélectionnez basicHttpBinding.

    5. Dans le champ BindingConfiguration , sélectionnez la liaison que vous avez créé précédemment. Dans ce cas, sélectionnez basicHttpConf.

    6. Cliquez sur le champ de Contracter et puis cliquez sur le bouton pour accéder au fichier exécutable qui contient le contrat WCF. Dans la boîte de dialogue Contrat de Type navigateur , accédez au fichier exécutable dans le sous-répertoire \bin\Debug du répertoire WCFHelloProject, cliquez sur le fichier WCFHelloProject.exe et puis cliquez sur Ouvrir. Le Contrat de Type navigateur affiche les classes de service dans le fichier exécutable (Figure 3) ; Cliquez sur SvcProject.Project et puis cliquez sur Ouvrir.

      Notes

      Visual Studio 2010 affiche une boîte de dialogue erreur avec le message, « Impossible de charger fichier ou l'assembly … » Vous pouvez également définir le type de service directement dans le champ du Contracter en tapant le nom de classe de service et d'espace de noms. Par exemple, tapez SvcProject.Project.

      Vous pouvez également voir le nom d'interface pour le contrat WCF dans l'Explorateur d'objets Visual Studio. Dans l'onglet Explorateur d'objets , développez le nœud WCFHelloProject. L'espace de noms SvcProject, par exemple, contient l'interface Project.

      La figure 3. À l'aide de l'Explorateur de types de contrat (avec Visual Studio 2008)

      Utilisation de l’explorateur de types de contrat

    7. Dans la même manière, créez un point de terminaison du service QueueSystem. Par exemple, nommez le point de terminaison basicHttp_QueueSystemet SvcQueueSystem.QueueSystem la valeur du champ de Contracter . Les autres champs dans le point de terminaison sont les mêmes que pour le point de terminaison du projet.

    8. Dans l' Éditeur de Configuration du Service Microsoft, dans le menu Fichier , cliquez sur Enregistreret fermez l'éditeur.

  10. Vérifiez le contenu du behaviors, bindings et endpoints des éléments dans le fichier app.config.

    <behaviors>
      <endpointBehaviors>
        <behavior name="basicHttpBehavior">
          <clientCredentials>
            <windows allowedImpersonationLevel="Impersonation" />
          </clientCredentials>
        </behavior>
        <!-- (More behaviors.) -->
      </endpointBehaviors>
    </behaviors>
     . . .
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpConf" sendTimeout="01:00:00" maxBufferSize="500000000"
            maxReceivedMessageSize="500000000">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="500000000" />
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm" realm="http//SecurityDomain" />
          </security>
        </binding>
      </basicHttpBinding>
      <!-- (More bindings.) -->
    </bindings>
    . . .
    <client>
      <endpoint address="https://ServerName/ProjectServerName/_vti_bin/PSI/ProjectServer.svc"
          behaviorConfiguration="basicHttpBehavior" binding="basicHttpBinding"
          bindingConfiguration="basicHttpConf" contract="SvcProject.Project"
          name="basicHttp_Project" kind="" endpointConfiguration="" />
      <endpoint address="https://ServerName/ProjectServerName/_vti_bin/PSI/ProjectServer.svc"
          behaviorConfiguration="basicHttpBehavior" binding="basicHttpBinding"
          bindingConfiguration="basicHttpConf" contract="SvcQueueSystem.QueueSystem"
          name="basicHttp_QueueSystem" />
      <!-- (More client endpoints.)-->
    </client>
    

    Conseil

    Après avoir créé le jeu de comportements, les liaisons et les points de terminaison qui fonctionnent pour un groupe de services WCF, vous pouvez utiliser ces sections dans le fichier app.config, comme le définit un modèle pour créer semblable, sans passer par le processus à l'aide de l' Éditeur de Configuration du Service Microsoft.

  11. Dans le fichier CreateProjects.cs, d'initialiser l'objet projectClient et l'objet queueSystemClient avec les noms de point de terminaison spécifiés dans app.config.

    Notes

    La méthode SetClientEndpoints ne doit pas le paramètre pwaUri car les paramètres de WCF sont dans app.config, non définis par programme en tant que procédure 3.

    private static void SetClientEndpoints()
    {
        projectClient = new backendProject.ProjectClient("basicHttp_Project");
        queueSystemClient = new backendQueueSystem.QueueSystemClient("basicHttp_QueueSystem");
    }
    
  12. Définissez les arguments de ligne de commande pour le débogage, comme dans la procédure 3, l'étape 6. Définissez un point d'arrêt dans la méthode SetClientEndpoints, étape les instructions et vérifiez les valeurs de certains paramètres de WCF, telles que la valeur de propriété de projectClient.ChannelFactory et la valeur de la propriété projectClient.Endpoint.

Lorsque le client de définir des points de terminaison et de l'application s'exécute correctement, vous pouvez utiliser les objets projectClient et queueSystemClient pour appeler les méthodes dans les services du projet et les services de QueueSystem de la PSI.

Programmation avec la PSI

Vous pouvez utiliser la procédure 3 (configuration par programmation) ou 4 de la procédure (à l'aide de app.config) pour initialiser l'objet projectClient et l'objet queueSystemClient avec des points de terminaison qui passent par le routeur ProjectServer.svc public dans Project Web App. Procédure 5 montre comment ajouter deux méthodes qui utilisent des appels PSI pour créer et supprimer des projets.

Procédure 5. Pour développer la méthode Create

  1. Préparer les données requises par les appels PSI. La méthode Create dans la classe CreateProjects effectue une itération sur la méthode QueueCreateProject pour le nombre de projets afin de créer. Les paramètres de QueueCreateProject sont jobUid (pour la file d'attente de Project Server travail GUID), dataset (qui est un objet ProjectDataSet avec un ProjectRow de chaque projet à créer) et validateOnly (qui spécifie s'il faut valider uniquement les données au lieu de créer le projet).

    L'objet projDs est instancié à partir de la définition de type ProjectDataSet dans l'alias d'espace de noms backendProject (vous pouvez trouver la définition de type dans le fichier reference.cs dans la référence de service SvcProject). L'objet projRow de ProjectRow de type doit être créé par la méthode NewProjectRow de la ProjectDataTable dans l'objet projDs, car la ligne de données du projet appartient à cet objet ProjectDataSet spécifique.

    Au moins trois propriétés sont nécessaire pour créer un projet : projet type, GUID du projet et nom du projet. Une fois ces propriétés sont définies dans la ligne du projet, la méthode AddProjectRow ajoute la ligne à l'objet projDs.

    public void Create()
    {
        // Prepare the data.
        Int32 projectType = Convert.ToInt32(PSLibrary.Project.ProjectType.Project);
        Guid[] projectUids = new Guid[numProjects];
        backendProject.ProjectDataSet[] projDs = new backendProject.ProjectDataSet[numProjects];
    
        for (int i = 0; i < numProjects; i++)
        {
            projectUids[i] = Guid.NewGuid();
            projDs[i] = new backendProject.ProjectDataSet();
            backendProject.ProjectDataSet.ProjectRow projRow = projDs[i].Project.NewProjectRow();
    
            projRow.PROJ_TYPE = projectType;
            projRow.PROJ_UID = projectUids[i];
            projRow.PROJ_NAME = "WCFTEST_" + projectUids[i].ToString();
    
            projDs[i].Project.AddProjectRow(projRow);
        }
        . . .
    }
    
  2. Appelez la méthode QueueCreateProject de l'objet projectClient (en d'autres termes, l'objet dont point de terminaison est le service ProjectServer.svc public) pour chaque ProjectDataSet. La sortie de console dans le code suivant correspond à l'application de test de WCFHelloProject afficher le temps nécessaire pour que le nombre d'appels spécifié.

    // Create the projects.
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine(string.Format("Creating {0} projects via WCF.",
                                    numProjects.ToString()));
    Console.ResetColor();
    
    DateTime startTime = DateTime.Now;
    
    for (int i = 0; i < numProjects; i++)
    {
        projectClient.QueueCreateProject((projectUids[i], projDs[i], false);
    }
    
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine("Time: {0} ms",
        (new TimeSpan((DateTime.Now.Ticks - startTime.Ticks))).TotalMilliseconds);
    Console.ResetColor();
    
  3. Pour les lignes restantes de la méthode Create, le code suivant utilise la méthode Helpers.WaitForQueue qui attend que le service de Project Server Queuing terminer la création de projets (voir la procédure 6). La méthode CreateProjects.Delete est expliquée dans l'étape suivante.

    Helpers.WaitForQueue(backendQueueSystem.QueueMsgType.ProjectCreate,
                         numProjects, queueSystemClient, startTime);
    
    if (deleteProjects) Delete(projectUids);
    
  4. Créez la méthode Delete dans la classe CreateProjects. Delete écrit des informations sur la console sur le nombre de projets, il est la suppression, appelle la méthode QueueDeleteProjects et écrit ensuite le nombre de millisecondes écoulées pour Project Server supprimer les projets.

    public void Delete(Guid[] projUids)
    {
        Console.Write("Deleting {0} project(s)...", numProjects);
    
        DateTime startTime = DateTime.Now;
        Guid jobUid = Guid.NewGuid();
    
        projectClient.QueueDeleteProjects(jobUid, true, projUids, true);
    
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine("\nTime: {0} ms",
            (new TimeSpan((DateTime.Now.Ticks - startTime.Ticks))).TotalMilliseconds);
        Console.ResetColor();
    
        Helpers.WaitForQueue(backendQueueSystem.QueueMsgType.ProjectDelete,
                             numProjects, queueSystemClient, startTime);
    }
    

Avant d'essayer de tester l'application, écrivez la classe Helpers avec la méthode WaitForQueue.

À l'aide du Service Queuing de Project Server

La méthode ReadMyJobStatus dans le service QueueSystem permet à une application lire l'état des types de travail spécifié dans le Service Queuing de Project Server et attendez que les tâches à effectuer. Si vous exécutez l'application WCFHelloProject sans attendre que la file d'attente, il essaie de supprimer les projets avant de chacun d'entre eux sont créés et lève une exception.

Procédure 6. Pour utiliser le service QueueSystem

  1. Ajouter une classe à l'application de WCFHelloProject qui possède une méthode d'utilitaire pour l'utilisation du service QueueSystem. Par exemple, dans le fichier CreateProjects.cs, ajoutez la classe Helpers avec une méthode WaitForQueue. WaitForQueue appellera la méthode ReadMyJobStatus dans le service de QueueSystem, qui possède des paramètres qui requièrent des types de travail vérifier, le nombre d'emplois, et heure de début. L'appel ReadMyJobStatus nécessite l'objet queueSystemClient pour accéder à la QueueSystem service via le routeur ProjectServer.svc front-end.

    class Helpers
    {
        public static bool WaitForQueue(backendQueueSystem.QueueMsgType jobType, int numJobs,
                                        backendQueueSystem.QueueSystemClient queueSystemClient,
                                        DateTime startTime)
        {
            . . .
        }
    }
    
  2. Dans la méthode WaitForQueue, ajoutez le code suivant. La constante maxSeconds2Wait permet l'application quitte la sous-routine s'il existe un problème ou si le Service Queuing de Project Server est trop long. La méthode ReadMyJobStatus renvoie un QueueStatusDataSet dans l'objet queueStatusDs.

    Alors que le nombre de travaux traités est inférieur au nombre total et le temps écoulé est inférieur à la valeur maximale spécifiée, appelez ReadMyJobStatus à chaque seconde (1000 millisecondes). Trier les résultats dans l'objet queueStatusDs par la colonne QueuePosition et le dernier ordre de tri.

    WaitForQueue renvoie true lors du traitement de tous les travaux de la file d'attente ou si le délai d'attente dépasse le temps maximal.

    const int maxSeconds2Wait = 50;
    backendQueueSystem.QueueStatusDataSet queueStatusDs = new backendQueueSystem.QueueStatusDataSet();
    
    int timeout = 0;    // Number of seconds waited.
    Console.Write("Waiting for job " + jobType.ToString());
    
    backendQueueSystem.QueueMsgType[] messageTypes = { jobType };
    backendQueueSystem.JobState[] jobStates = { backendQueueSystem.JobState.Success };
    
    while ((timeout < maxSeconds2Wait) && (queueStatusDs.Status.Count < numJobs))
    {
        System.Threading.Thread.Sleep(1000);
    
        queueStatusDs = queueSystemClient.ReadMyJobStatus(
            messageTypes,
            jobStates,
            startTime,
            DateTime.Now,
            numJobs,
            true,
            backendQueueSystem.SortColumn.QueuePosition,
            backendQueueSystem.SortOrder.LastOrder);
    
        timeout++;
        Console.Write(".");
    }
    Console.WriteLine();
    
    if (queueStatusDs.Status.Count == numJobs)
    {
        return true;
    }
    return false;
    
  3. Ne pas commenter les deux lignes suivantes dans la classe Program.Main, pour exécuter et tester l'application.

    projectCreator.Create();
    projectCreator.DisposeClients();
    
  4. Débogage : Pour vérifier plus facilement le contenu d'un DataSet, utilisez l'outil visualiseur DataSet. Par exemple, définir un point d'arrêt sur la ligne if (queStatusDS.Status.Count == numJobs) dans la méthode WaitForQueue. Lorsque l'application atteint le point d'arrêt, placez le pointeur de la souris sur queueStatusDs et puis cliquez sur l'icône de loupe petit dans la valeur de débogage de fenêtres pop-up. La figure 4 illustre la boîte de dialogue Visualiseur DataSet . Vous pouvez visuellement examiner toutes les propriétés des lignes dans une table de la DataSet ou copier les datarows dans un éditeur de texte. La QueueStatusDataSet contient la table d'état. Étant donné que l'exécution par défaut de WCFHelloProject crée deux projets, le Service de Project Server Queuing s'exécute uniquement deux tâches de file d'attente de MessageType = 22 pour l'utilisateur de l'application. L'énumération QueueConstants.QueueMessageType dans l'espace de noms Microsoft.Office.Project.Server.Library (QueueConstants.QueueMsgType) indique que la valeur de type de message 22 est ProjectCreate.

    La figure 4. En utilisant le visualiseur DataSet pour le débogage

    Utilisation du visualiseur de DataSet

Si vous exécutez l'application WCFHelloProject plusieurs fois en succession rapide, le travail de la file d'attente diminuent généralement de plusieurs séries des heures et ensuite restent proches en valeur à la précédente exécution après environ trois ou quatre s'exécute. Par exemple, la sortie suivante de cinq séries montre une diminution excellente moment après l'exécution initiale. C'est parce qu'un algorithme du système de projet serveur Queuing conserve un enregistrement interne des types et la fréquence des travaux de la file d'attente et ajuste la file d'attente pour traiter plus rapidement, de travaux similaires s'ils proviennent en succession rapide. Ainsi, Project Server peut gérer plus efficacement un afflux rapid de travaux similaires, tels que les envois de la feuille de temps. Pour plus d'informations sur le service QueueSystem, voir How to: Use the QueueSystem Service.

URL: https://localhost:80/pwa/
Creating 2 projects via WCF.
Time: 57004.164 ms
Waiting for job ProjectCreate.......
Deleting 2 project(s)...
Time: 852.4845 ms
Waiting for job ProjectDelete.
_________________________________
URL: https://localhost:80/pwa/
Creating 2 projects via WCF.
Time: 3779.055 ms
Waiting for job ProjectCreate.
Deleting 2 project(s)...
Time: 1267.497 ms
Waiting for job ProjectDelete.
_________________________________
URL: https://localhost:80/pwa/
Creating 2 projects via WCF.
Time: 2144.394 ms
Waiting for job ProjectCreate.
Deleting 2 project(s)...
Time: 350.5635 ms
Waiting for job ProjectDelete.
_________________________________
URL: https://localhost:80/pwa/
Creating 2 projects via WCF.
Time: 1719.6165 ms
Waiting for job ProjectCreate.
Deleting 2 project(s)...
Time: 335.916 ms
Waiting for job ProjectDelete..
_________________________________
URL: https://localhost:80/pwa/
Creating 2 projects via WCF.
Time: 2259.621 ms
Waiting for job ProjectCreate.
Deleting 2 project(s)...
Time: 361.305 ms
Waiting for job ProjectDelete.

Le WCFHelloProject à l'application utilise les appels à la PSI via WCF pour créer un certain nombre de projets dans la base de données de brouillons de Project Server et indique ensuite le temps nécessaire pour créer et supprimer des projets. Vous pouvez définir des points de terminaison pour les objets de client PSI en configuration par programmation ou en utilisant des app.config et l' Éditeur de Configuration du Service Microsoft dans Visual Studio. La figure 5 illustre une capture d'écran de la fenêtre de console pour l'application en cours d'exécution.

La figure 5. Sortie de la fenêtre console de WCFHelloProject.exe

Affichage de la fenêtre de la console de WCFHelloProject

Exemple de Code complet

Voici le code complet dans le fichier Program.cs. La méthode ParseCommandLine dans la classe Program valide les arguments de ligne de commande. La méthode Main instancie l'objet CreateProjects.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WCFHelloProject
{
    class Program
    {
        static private Uri pwaUri;          // URI of Project Web App.
        static private string pwaUrl;       // URL of Project Web App.
        static private string argError;     // Contains the argument that is in error.

        static private int numProjects;     // Number of projects to create.
        static private bool deleteProjects; // Specifies whether to delete projects.

        static void Main(string[] args)
        {
            pwaUrl = string.Empty;
            pwaUri = null;
            numProjects = 2;
            deleteProjects = true;
            argError = null;

            if (args.Length == 0)
            {
                Usage(argError);
            }
            else if (ParseCommandLine(args))
            {
                // The command is valid, so instantiate the CreateProjects object.
                CreateProjects projectCreator = 
                    new CreateProjects(pwaUri, numProjects, deleteProjects);

                projectCreator.Create();
                projectCreator.DisposeClients();
            }
            else
            {
                Usage(argError);
            }
            // Keep the Command Prompt window open for debugging.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey(true);
        }

        // Parse the command line.
        static private bool ParseCommandLine(string[] args)
        {
            const int MAXNUM = 20;
            bool error = false;
            bool argErr = false;

            int argsLength = args.Length;

            for (int i = 0; i < args.Length; ++i)
            {
                if (error) break;

                switch (args[i].ToLower())
                {
                    case "/pwaurl":
                    case "-pwaurl":
                        i++;
                        if (i >= argsLength) return false;
                        pwaUrl = args[i];

                        if (pwaUrl.ToLower().StartsWith("http"))
                        {
                            // Add a trailing slash, if it is not present.
                            if (pwaUrl.LastIndexOf("/") != pwaUrl.Length - 1)
                                pwaUrl += "/";

                            // Convert to a URI, for easier access to properties.
                            pwaUri = new Uri(pwaUrl);
                        }
                        else
                            argErr = true;
                        break;

                    case "/numprojects":
                    case "-numprojects":
                        i++;
                        if (i >= argsLength) return false;
                        numProjects = Convert.ToInt32(args[i]);

                        if (numProjects < 0 || numProjects > MAXNUM) argErr = true;
                        break;

                    case "/delete":
                    case "-delete":
                        i++;
                        if (i >= argsLength) return false;

                        string theArg = args[i].ToLower();

                        switch (theArg)
                        {
                            case "t":
                            case "true":
                            case "1":
                                deleteProjects = true;
                                break;
                            case "f":
                            case "false":
                            case "0":
                                deleteProjects = false;
                                break;
                            default:
                                argErr = true;
                                break;
                        }
                        break;

                    case "/?":
                    case "-?":
                        error = true;
                        break;

                    default:
                        argError = args[i];
                        error = true;
                        break;
                }
            }
            if (pwaUrl == string.Empty) error = true;
            if (argErr) error = true;

            return !error;
        }

        // Show the command usage.
        static private void Usage(String errorInfo)
        {
            if (errorInfo != null)
            {
                // A command-line argument error occurred. Report it to the user.
                Console.WriteLine("Error: {0} is not an argument.\n", errorInfo);
            }

            Console.WriteLine(string.Format(
                "Usage:  [/?] -{0} {1} [-{2} {3}] [-{4} {5}]",
                "pwaUrl", @"""<URL>""",
                "numProjects", "<0 - 20>",
                "delete", "<T | F>"));

            Console.WriteLine(
                "\n\tpwaUrl:\t\tExample: https://ServerName/pwa"
                + "\n\n\tnumProjects:\tOptional. Number of projects to create."
                + "\n\t\t\tThe default is 2; maximum is 20."
                + "\n\n\tdelete:\t\tOptional. Delete projects after creating them."
                + "\n\t\t\tThe default is true.");
        }   
    }
}

Voici le code complet pour la classe CreateProjects et la classe Helpers dans le fichier CreateProjects.cs. La méthode SetClientEndpoints définit les points de terminaison clients par programme plutôt qu'avec app.config. Pour l'exemple de code qui utilise app.config, consultez le répertoire WCFHelloProject_vs10_CfgEd dans le téléchargement du Kit de développement de Project 2010.

using System;
using System.Net;
using System.ServiceModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSLibrary = Microsoft.Office.Project.Server.Library;
using backendProject = WCFHelloProject.SvcProject;
using backendQueueSystem = WCFHelloProject.SvcQueueSystem;

namespace WCFHelloProject
{
    class CreateProjects
    {
        private static backendProject.ProjectClient projectClient;
        private static backendQueueSystem.QueueSystemClient queueSystemClient;
        private static string pwaUrl;
        private static int numProjects;
        private static bool deleteProjects;

        public CreateProjects(Uri uri, int num, bool delete)
        {
            numProjects = num;
            deleteProjects = delete;
 
           SetClientEndpoints(uri);
        }

        private static void SetClientEndpoints(Uri pwaUri)
        {
            const int MAXSIZE = 500000000;
            const string svcRouter = "_vti_bin/PSI/ProjectServer.svc";

            pwaUrl = pwaUri.Scheme + Uri.SchemeDelimiter + pwaUri.Host + ":"
                + pwaUri.Port + pwaUri.AbsolutePath;
            Console.WriteLine("URL: {0}", pwaUrl);

            // Create a binding for HTTP.

            BasicHttpBinding binding = null;

            if (pwaUri.Scheme.Equals(Uri.UriSchemeHttps))
            {
                // Create binding for HTTPS.
                binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
            }
            else
            {
                // Create binding for HTTP.
                binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
            }

            binding.Name = "basicHttpConf";
            binding.SendTimeout = TimeSpan.MaxValue;
            Console.WriteLine("SendTimeout value:\n\t{0} days,\n\t{1} hours,\n\t{2} minutes,\n\t{3} seconds",
                binding.SendTimeout.Days.ToString(), binding.SendTimeout.Hours.ToString(),
                binding.SendTimeout.Minutes.ToString(), binding.SendTimeout.Seconds.ToString());

            binding.MaxReceivedMessageSize = MAXSIZE;
            binding.ReaderQuotas.MaxNameTableCharCount = MAXSIZE;
            binding.MessageEncoding = WSMessageEncoding.Text;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;

            // The endpoint address is the ProjectServer.svc router for all public PSI calls.
            EndpointAddress address = new EndpointAddress(pwaUrl + svcRouter);

            projectClient = new backendProject.ProjectClient(binding, address);
            projectClient.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel
                = TokenImpersonationLevel.Impersonation;
            projectClient.ChannelFactory.Credentials.Windows.AllowNtlm = true;

            queueSystemClient = new backendQueueSystem.QueueSystemClient(binding, address);
            queueSystemClient.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel
                = TokenImpersonationLevel.Impersonation;
            queueSystemClient.ChannelFactory.Credentials.Windows.AllowNtlm = true;
        }

        public void DisposeClients()
        {
            projectClient.Close();
            queueSystemClient.Close();
        }

        public void Create()
        {
            // Prepare the data.
            Int32 projectType = Convert.ToInt32(PSLibrary.Project.ProjectType.Project);
            Guid[] projectUids = new Guid[numProjects];
            backendProject.ProjectDataSet[] projDs = new backendProject.ProjectDataSet[numProjects];

            for (int i = 0; i < numProjects; i++)
            {
                projectUids[i] = Guid.NewGuid();
                projDs[i] = new backendProject.ProjectDataSet();
                backendProject.ProjectDataSet.ProjectRow projRow = projDs[i].Project.NewProjectRow();

                projRow.PROJ_TYPE = projectType;
                projRow.PROJ_UID = projectUids[i];
                projRow.PROJ_NAME = "WCFTEST_" + projectUids[i].ToString();

                projDs[i].Project.AddProjectRow(projRow);
            }

            // Create the projects.
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(string.Format("Creating {0} projects via WCF.",
                                            numProjects.ToString()));
            Console.ResetColor();

            DateTime startTime = DateTime.Now;

            for (int i = 0; i < numProjects; i++)
            {
                projectClient.QueueCreateProject(projectUids[i], projDs[i], false);
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Time: {0} ms",
                (new TimeSpan((DateTime.Now.Ticks - startTime.Ticks))).TotalMilliseconds);
            Console.ResetColor();

            Helpers.WaitForQueue(backendQueueSystem.QueueMsgType.ProjectCreate,
                                 numProjects, queueSystemClient, startTime);

            if (deleteProjects) Delete(projectUids);
        }

        public void Delete(Guid[] projUids)
        {
            Console.Write("Deleting {0} project(s)...", numProjects);

            DateTime startTime = DateTime.Now;
            Guid jobUid = Guid.NewGuid();

            projectClient.QueueDeleteProjects(jobUid, true, projUids, true);

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("\nTime: {0} ms",
                (new TimeSpan((DateTime.Now.Ticks - startTime.Ticks))).TotalMilliseconds);
            Console.ResetColor();

            Helpers.WaitForQueue(backendQueueSystem.QueueMsgType.ProjectDelete,
                                 numProjects, queueSystemClient, startTime);
        }
    }

    class Helpers
    {
        public static bool WaitForQueue(backendQueueSystem.QueueMsgType jobType, int numJobs,
                                        backendQueueSystem.QueueSystemClient queueSystemClient,
                                        DateTime startTime)
        {
          const int maxSeconds2Wait = 50;
          backendQueueSystem.QueueStatusDataSet queueStatusDs = new backendQueueSystem.QueueStatusDataSet();

            int timeout = 0;    // Number of seconds waited.
            Console.Write("Waiting for job " + jobType.ToString());

            backendQueueSystem.QueueMsgType[] messageTypes = { jobType };
            backendQueueSystem.JobState[] jobStates = { backendQueueSystem.JobState.Success };

            while ((timeout < maxSeconds2Wait) && (queueStatusDs.Status.Count < numJobs))
            {
                System.Threading.Thread.Sleep(1000);

                queueStatusDs = queueSystemClient.ReadMyJobStatus(
                    messageTypes,
                    jobStates,
                    startTime,
                    DateTime.Now,
                    numJobs,
                    true,
                    backendQueueSystem.SortColumn.QueuePosition,
                    backendQueueSystem.SortOrder.LastOrder);

                timeout++;
                Console.Write(".");
            }
            Console.WriteLine();

            if (queueStatusDs.Status.Count == numJobs)
            {
                return true;
            }
            return false;
        }
    }
}

Notes

Avertissement traduction automatique : cet article a été traduit par un ordinateur, sans intervention humaine. Microsoft propose cette traduction automatique pour offrir aux personnes ne maîtrisant pas l’anglais l’accès au contenu relatif aux produits, services et technologies Microsoft. Comme cet article a été traduit automatiquement, il risque de contenir des erreurs de grammaire, de syntaxe ou de terminologie.

Étapes suivantes

Le code dans l'exemple de WCFHelloProject n'inclut pas les instructions de Try … Catch, pour maintenir le code plus facile à suivre pour la discussion. L'exemple de code est fourni uniquement comme une application de test pour s'exécuter sur une installation d'essai de Project Server, mais doit avoir des gestionnaires d'exceptions autour des sections qui utilisent la PSI. Les exceptions typiques pour les appels WCF pour la PSI sont EndpointNotFoundException et CommunicationException.

L'exemple de code utilise un base de transport HTTP pour la communication. Vous pouvez également créer des points de terminaison qui utilisent la couche transport TCP client et ensuite comparer la vitesse lors de l'exécution de l'application sur un ordinateur externe. L'ordinateur externe doit avoir le.NET Framework 3.5 SP1 est installé.

Voir aussi

Tâches

Procédure pas à pas : Personnalisation du ruban PWA et accès au JS Grid (traduction automatique)

How to: Use the QueueSystem Service

Concepts

Vue d’ensemble de WCF et de l’interface PSI (traduction automatique)

Conditions préalables pour les exemples de code basés sur WCF (traduction automatique)

Autres ressources

Programming WCF Security

Claims-Based Architectures

Transport Security Overview

Beginner's Guide to Windows Communication Foundation

What's New: Client Object Model