viernes, 29 de junio de 2012

Invoke Web Service make in WCF with a client in PHP

Context.
I have a a web service  implementation in .net with WCF and publish in a SSL channel, and i want to call this WS from a client in PHP.

I tried install WSF from WSO2 and it's impossible i have an error API PHP it's diferent to API WSO2 and dont load the wsf.dll. it's a nightmare.

And so, implement a SOAPclient but i find errors that

The message with To '' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher.  Check that the sender and receiver's EndpointAddresses agree.
thanks to 
http://blogs.msdn.com/b/nabeelp/archive/2008/03/07/obscure-error-addressfilter-mismatch-at-the-endpointdispatcher.aspx
i find the solution

class Soap {

    public $proxy=null;

    public function Soap($myAction){
       
        $this->proxy = new My_SoapClient("https://www.domain.eu/Service.svc?wsdl",
       
           array(
               'trace' => 1,
               'soap_version' => SOAP_1_2 ,
               'SOAPAction'=> $myAction ,
               'location'=>'https://www.domain.eu/Service.svc'

               )
        );
        //create a Head soap message to connect  with WCF
        $actionHdr[] = new SoapHeader("http://www.w3.org/2005/08/addressing", 'Action', $myAction);
        $actionHdr[] = new SoapHeader("http://www.w3.org/2005/08/addressing", 'To', 'https://www.domain.eu/Service.svc',  1);
        $this->proxy->__setSoapHeaders($actionHdr);
    }

}




class My_SoapClient extends SoapClient {

    protected $_response = null;
    // overwrite SoapClient send message
    public function __doRequest( $request, $location, $action, $version, $one_way = nul) {

            $curl = curl_init($location);
            $headers = array(            
            "Content-type:application/soap+xml;charset=\"utf-8\"",
            "Accept: text/xml",
            "Cache-Control: no-cache",
            "Pragma: no-cache",
            "SOAPAction: ". $action,
              );

            //http://php.net/manual/en/function.curl-setopt.php
            curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,2);//dont change this value. read the link
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            // list of trush Certificate. only work in absolute path... i dont know
            curl_setopt($curl,CURLOPT_CAINFO,'Cert.pem');
            curl_setopt($curl,CURLOPT_VERBOSE,false);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($curl, CURLOPT_POST, TRUE);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
         
            $response = curl_exec($curl);
            if (curl_errno($curl)) {
                throw new Exception(curl_error($curl));
            }
            curl_close($curl);
            if (!$one_way) {
                return ($response);
            }
        }
}
//and  for each operation, implements


class OperationOne{
    public $soap=null;

    public  function Request(){
            $this->soap = new Soap('https://www.domain.eu/OperationOne);
    }
}

//to make the invoke
 $operationOne = new OperationOne();//create soap message
$parametreOut= $operationOne->soap->proxy->openSessionOperation($parameterIn);


miércoles, 27 de junio de 2012

Generacion de WSDL en un domino y el servicio está hostepado en una maquina local

Cuando tienes un servicio creado con WCF y se generan los ficheros WSDL, si el servicio esta en una maquina local y lo que quieres hacer es que se publique contra un dominio especifico tienes que hacer lo siguiente


    1.- En mi caso no tenia instaladas las herramientas administrativas del IIS 7 y estas se instalan Panel de control\Todos los elementos de Panel de control\activar desactivar las caracteristicas de windows



2. - Sacar la consola  cmd en modo administrativo y lanzar el siguiente comando
   
    %systemroot%\system32\cscript.exe //nologo c:\inetpub\AdminScripts\adsutil.vbs set /w3svc/NUMERO/SecureBindings :443:www.dominiopublico.es

    Donde numero es el ID del servidor del IIS seguro, en mi caso el número = 2




3.- reiniciar el IIS con la instrucción
iisreset


Si no funciona se puede volver al estado anterior ejecutando
 %systemroot%\system32\cscript.exe //nologo c:\inetpub\AdminScripts\adsutil.vbs set /w3svc/NUMERO/SecureBindings :443:




[1]http://www.jstawski.com/archive/2008/05/01/wcf-wsdl-location-address-with-https.aspx

[2]http://www.codemeit.com/wcf/wcf-wsdl-xsdimport-schemalocations-link-to-local-machine-name-not-domain-name-while-hosted-in-iis.html