WCF et Client PHP avec paramètres de type non standard

J’ai été confronté récemment, chez mon client, à un problème de communication entre un service WCF et un client PHP.

Je parvenais correctement à dialoguer avec le service, sans jamais réussir à lui fournir de paramètres. Pourtant le WSDL définissait bien mes paramètres attendus et mon appel était construit de façon à lui fournir ces paramètres :


$client = new SoapClient('http://adresse-externe/WebService.svc?wsdl');

$params= array('LOGIN' => 'toto');

$result = $client->CONNEXION($params);

$result = $client->__soapCall('CONNEXION', array('parameters' => $params));

Et pourtant, en analysant la requête SOAP générée (requête de communication qui transitent entre le client et le service), je ne retrouvais aucun des paramètres dans le corps de l’enveloppe.


<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://adresse-externe:81/">
    <SOAP-ENV:Body>
        <ns1:CONNEXION/>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Je m’attendais à recevoir une requête contenant explicitement mon paramètre:


<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://adresse-externe:81/">
    <SOAP-ENV:Body>
        <ns1:CONNEXION>
            <ns1:LOGIN>toto</ns1:LOGIN>
        </ns1:CONNEXION>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Après plusieurs essais côté PHP, je me suis finalement tourné vers WCF pensant que le problème venait de là.

En effet, ma méthode CONNEXION est définie ainsi:


public CONNEXIONResponse CONNEXION(CONNEXION pConnexion)
{
    //Traitements connexion
}

Elle attend un objet de type CONNEXION en paramètre. Ce type étant un type spécifique (une classe définie côté serveur) et le client Php n’en ayant pas connaissance, je dois forcer le message SOAP à prendre en compte les paramètres.

Pour être plus précis, ce n’est pas l’entité que je vais rendre disponible mais c’est la façon dont va être appelée la méthode CONNEXION qui va changer.
Côté client, l’appel se fait en passant un tableau de paramètre à ma méthode. De ce fait, je dois formater le WSDL de sorte que mon entité CONNEXION attendu par ma méthode CONNEXION soit décomposé.

L’appel en C# ne se fait plus en instanciant un objet:

WebServiceClient client = new WebServiceClient();
CONNEXION entity = new CONNEXION() { LOGIN = "toto" };
var r = client.CONNEXION(entity)

Mais passant les propriétés de l’objet attendu, directement en paramètre:

bool isOk = false;
WebServiceClient client = new WebServiceClient();
client.CONNEXION(out isOk, "toto");

Mon paramètre de retour isOk est un boolean correspondant à une propriété de type boolean définit dans ma classe CONNEXIONResponse

Et tout cela se fait simplement en remplaçant l’attribut [DataContract] et [DataMember] de ma classe CONNEXION par les attributs [MessageContract] et [MessageBodyMember] :


        //[DataContract]
        [MessageContract]
        public partial class CONNEXION
        {
            //[DataContract]
            [MessageBodyMember]
            public string LOGIN { get; set; }
        }

Ainsi, vous construisez votre requête SOAP comme vous le désirez.

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s