How to make your webservice SOAP 1.2 in Yii
when i set up client to be v1.2 i always receive v1.2 response from server, and when i set up client to be v1.1 i always receive v1.1 response from server, maybe it auto-detects client version and overrides server version with it?
$client=new SoapClient('http://hys.local/ABFolio/folio',array('soap_version'=>SOAP_1_2,'trace'=>true));
var_dump($client);
echo $client->sendFolio();
echo $client->__getLastRequest();
echo $client->__getLastResponse();
response is 1.2
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"
and with 1.1 which default for client
$client=new SoapClient('http://hys.local/ABFolio/folio',array('soap_version'=>SOAP_1_1,'trace'=>true));
response is 1.1
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
EDIT:
lets look inside yii
framework\web\services\CWebService.php
/**
* @return array options for creating SoapServer instance
* @see http://www.php.net/manual/en/function.soap-soapserver-construct.php
*/
protected function getOptions()
{
$options=array();
if($this->soapVersion==='1.1')
$options['soap_version']=SOAP_1_1;
else if($this->soapVersion==='1.2')
$options['soap_version']=SOAP_1_2;
if($this->actor!==null)
$options['actor']=$this->actor;
$options['encoding']=$this->encoding;
foreach($this->classMap as $type=>$className)
{
$className=Yii::import($className,true);
if(is_int($type))
$type=$className;
$options['classmap'][$type]=$className;
}
return $options;
}
i don't see any error in your code if i check this code
EDIT:
ok, how about this than? framework\web\services\CWsdlGenerator.php
/*
* @param DOMDocument $dom Represents an entire HTML or XML document; serves as the root of the document tree
*/
private function addBindings($dom)
{
$binding=$dom->createElement('wsdl:binding');
$binding->setAttribute('name',$this->serviceName.'Binding');
$binding->setAttribute('type','tns:'.$this->serviceName.'PortType');
$soapBinding=$dom->createElement('soap:binding');
$soapBinding->setAttribute('style','rpc');
$soapBinding->setAttribute('transport','http://schemas.xmlsoap.org/soap/http');
$binding->appendChild($soapBinding);
$dom->documentElement->appendChild($binding);
foreach($this->_operations as $name=>$doc)
$binding->appendChild($this->createOperationElement($dom,$name));
}
as i can see transport is predefined (you can check and replace it to 12)
my wsdl becomes this after adding 12
<wsdl:binding name="ABFolioControllerBinding" type="tns:ABFolioControllerPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap12/http"/>
</wsdl:binding>
maybe it's bug in yii - go ahead and report it then
but as from http://msdn.microsoft.com/en-us/library/ms995800.aspx
i was checking not a transport but namespace
SOAP versioning is based on XML namespaces. SOAP 1.1 is identified by the http://schemas.xmlsoap.org/soap/envelope/ namespace while SOAP 1.2 is identified by the http://www.w3.org/2002/12/soap-envelope namespace (although this will change when it becomes a Recommendation).
that's why i thought all is correct
EDIT:
here's decesion, you need to have
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
inside <definitions
in your xml in addition to
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
and instead of this:
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
you must place
<soap12:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
now soapUI detects my wsdl as soap 1.2
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="urn:ABFolioControllerwsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/"
name="ABFolioController"
targetNamespace="urn:ABFolioControllerwsdl">
<wsdl:portType name="ABFolioControllerPortType"/>
<wsdl:binding name="ABFolioControllerBinding" type="tns:ABFolioControllerPortType">
<soap12:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
</wsdl:binding>
<wsdl:service name="ABFolioControllerService">
<wsdl:port name="ABFolioControllerPort" binding="tns:ABFolioControllerBinding">
<soap:address location="http://hys.local/uk/aBFolio/folio?ws=1"/>
</wsdl:port>
</wsdl:service>
</definitions>
all replacement you can do in same files in yii in addBindings
and buildDOM
functions
also i think it much harder, i.e. you must have both soap and soap12 bindings if you want to support both, but at least it already recognized as soap12
EDIT:
yii hardcoded soap1.1 if you don't provide your own wsdl (you can provide it via $wsdlUrl as in run method of CWebService). it seems legit - becouse default soap version in php soap server is 1.1 too, if you changing your version to 1.2 you must provide your own wsdl for 1.2
Comments
-
k to the z over 1 year
The Problem:
I can't figure out how Yii expects me to change the soap version. I'm following this tutorial. The web service works, but it isn't SOAP 1.2
The Class:
<?php class ABFolioController extends CController { public function actions() { return array( 'folio'=>array( 'class'=>'CWebServiceAction', 'serviceOptions'=>array('soapVersion'=>'1.2') ), ); } /** * @param string folioId * @param string cNumber * @param string oDRS * @param string dlr * @param string feeAmount * @param string transactionStatus * @param string captureId * @param datetime captureTimestamp * @param string prefix * @param string oDEFRS * @return string the statement * @soap */ public function sendFolio($folioId, $cNumber, $oDRS, $dlr, $feeAmount, $transactionStatus, $captureId, $captureTimestamp, $prefix, $oDEFRS) { // $model = new Dlfolio(); $model->folioId = $folioId; $model->cNumber = $cNumber; $model->oDRS = $oDRS; $model->dlr = $dlr; $model->feeAmount = $feeAmount; $model->transactionStatus = $transactionStatus; $model->captureId = $captureId; $model->captureTimestamp = $captureTimestamp; $model->prefix = $prefix; $model->oDEFRS = $oDEFRS; $yesno = $model->save(); if ($yesno=TRUE) { //on success return 'Record Saved'; } else { //on failure return $yesno; } } }
-
k to the z over 11 yearsThis is about how to call this in the Yii framework. Not regular php. Thank you for the response though.
-
llamerr over 11 yearsand how do you think what soap server yii use? not php default? i'm just saying that maybe php server version is always overrided by client version
-
k to the z over 11 yearsllamerr, this is a framework specific question. There is a class with a specific property for this. I'm obviously incorrectly calling the property and want to know the correct way to do it within the framework. I know how to use the php soapClient. That's not what my question is about. If I wanted to use it without the framework on top I would, but that's not my question.
-
llamerr over 11 yearsi understand that its a framework specific question, but how do you determine that your soap version is set incorrectly?
-
llamerr over 11 yearsi don't know if schemas.xmlsoap.org/soap12/http is correct transport, maybe it must be something else
-
llamerr over 11 yearsbtw, are you sure that soap version is determined by
<soap:binding style="rpc" transport=
? schemas.xmlsoap.org/wsdl/soap12/soap12WSDL.htm here i can see that transport is the same, but namespace changed(it also predefined in same file in yii) -
k to the z over 11 yearsThere are probably a few thing that make something 1.1
-
k to the z over 11 yearsAlright it looks like you're right. I'll mark your question as correct and award the bounty in four days. That way someone else can comment if they think we are wrong. I can't believe yii hard coded the web service to 1.1
-
llamerr over 11 yearsno, yii hardcoded soap1.1 if you don't provide your own wsdl, you can provide it via
$wsdlUrl
as inrun
method ofCWebService
-
llamerr over 11 yearsalso it seems legit - becouse default soap version in php soap server is 1.1 too, if you changing your version to 1.2 you must provide your own wsdl for 1.2