• Blog
  • Bio

Eric Boumendil

Implémenter un service web en PHP avec nuSoap et le consommer avec .NET

14 mars 2010 // archives .net c#
Cet article est très ancien. Les choses ont bien changées depuis 2010. Le sujet abordé est conservé pour référence mais n'est certainement plus applicable en l'état.
Cet article est susceptible de référencer des images manquantes ou de contenir des erreurs de formatage sur son contenu. Il s'agit d'un import provenant d'un ancien blog.

Il s’agit d’un exemple rudimentaire et je n’entre pas dans les détails, ni sur PHP, ni sur les services web. Le seul but de ce billet est d’illustrer un cas simple de création de service en PHP et de sa consommation en .NET sans “magie”.

Implémentation du service web en PHP

Cet exemple se base sur le tutoriel http://www.sanity-free.org/125/php_webservices_and_csharp_dotnet_soap_clients.html. Je m’en distingue par le fait que l’on n’utilisera pas la génération automatique de code avec la fonction Add Service Reference de VS.

Pré-requis

Le répertoire de la librairie nuSoap (version utilisée ici: 0.7.3) doit être placé à côté du fichier du script php qui suit.

Script PHP

 1<?php
 2
 3require_once("nusoap/lib/nusoap.php");
 4$namespace = "http://www.eric-bml.net/service";
 5$server = new soap_server();
 6$server->soap_defencoding = 'UTF-8';
 7$server->configureWSDL("SimpleService");
 8$server->wsdl->schemaTargetNamespace = $namespace;
 9
10$server->register(
11                // method name:
12                'ProcessSimpleType',
13                // parameter list:
14                array('name'=>'xsd:string'),
15                // return value(s):
16                array('return'=>'xsd:string'),
17                // namespace:
18                $namespace,
19                // soapaction: (use default)
20                false,
21                // style: rpc or document.
22                'document',
23                // use: encoded or literal
24                'literal',
25                // description: documentation for the method
26                'A simple Hello World web method');
27
28// Get our posted data if the service is being consumed
29// otherwise leave this data blank.
30$POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA'])
31                ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
32
33// pass our posted data (or nothing) to the soap service
34$server->service($POST_DATA);
35//$server->service(utf8_encode($POST_DATA));
36exit();
37
38function ProcessSimpleType($who) {
39	return "Hello $who";
40}
41
42?>

Plusieurs remarques importantes

Espace de nom

Notez que l’espace de nom (namespace, ligne 4) est ignoré par nuSoap. Ce dernier retournera l’espace de nom de la requête dans sa réponse, c’est-à-dire celui qui sera défini dans notre contrat .NET un peu plus loin.

Format (style) des messages SOAP

La ligne 22 est importante: elle définit le style (nommé format dans .NET) document. Par défaut, .NET s’attendra à ce format. Si vous choisissez rpc, il faudra l’expliciter dans le contrat .NET.

Testez la page PHP

Avant de continuer, assurez-vous que la page PHP est bien accessible par un navigateur. Pour la suite, nous considérerons que le service est accessible à cette adresse:

La capture d’écran de la page PHP qui illustrait ce paragraphe n’a été conservée par aucune archive du web.

Consommer le service dans un projet .NET

Il y a deux étapes :

  • Définir le contrat du service (une interface).

  • Instancier un client.

Contrat

Pour cet exemple simple, le projet du contrat ne contient qu’une interface :

 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5using System.ServiceModel;
 6
 7namespace Service.Contract
 8{
 9
10    [ServiceContract(Namespace = "http://www.eric-bml.net/service")]
11    public interface ITestService
12    {
13        [OperationContract]
14        [return: System.ServiceModel.MessageParameterAttribute(Name = "return")]
15        string ProcessSimpleType(string name);
16    }
17}

Remarquez bien la ligne 14. Sans elle, .NET retournera toujours une valeur null.

Client

Le projet du client doit référencer le projet du contrat. Dans cet exemple, il s’agit d’une application Console:

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

using Service.Contract;

namespace Service.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
            EndpointAddress endPointAddr = new EndpointAddress("http://blog.eric-bml.net/public/phpservice/hello.service.php");
            ITestService testService = new ChannelFactory<ITestService>(binding, endPointAddr).CreateChannel();

            string message = testService.ProcessSimpleType("World");
            if (message == null)
                Console.WriteLine("Echec: la méthode a retourné null.");
            else
                Console.WriteLine("Réponse: '" + message + "'");
            Console.ReadKey();
        }
    }
}

Si vous n’avez pas fait d’erreur, vous devriez obtenir “Réponse: ‘Hello World’”.

En cas de problème…

Les deux cas que j’ai rencontré sont:

  • une CommunicationException (contenant une erreur SOAP),

  • la valeur retournée est null.

Dans le premier cas, il s’agit a priori de l’interface qui contient une erreur (par exemple, mauvais nom de méthode). Dans le second cas, et c’est le plus dur à déboguer, le problème se situe généralement au niveau de la désérialisation côté client. Il peut y avoir un problème d’espace de nom discordant (néanmoins, cela ne devrait pas arriver dans cet exemple car nuSoap s’adapte à l’espace de nom de la requête). Il peut s’agir d’une mauvaise configuration pour la désérialisation, notamment le format des messages (document ou RPC).

Si le service web est fonctionnel, une technique est d’utiliser Fiddler pour vérifier que le service retourne bien une réponse. Puis d’utiliser la fonction de génération de code de VS en fournissant l’adresse du service, suffixée de “?wsdl”. Enfin, d’éditer le fichier généré (caché par défaut) “Reference.cs” et de comparer les attributs du contrat généré avec le vôtre.

Références

http://www.scottnichol.com/nusoapintro.htm

http://www.sanity-free.org/125/php_webservices_and_csharp_dotnet_soap_clients.html

http://www.fiddler2.com/fiddler2/

← 
Réutiliser une librairie .NET dans un projet Silverlight
Service Memcached pour Windows x64
 →
 
© 2026 Eric Boumendil
Haut de page