nusoap WebService error with .NET 解决方案
nusoap WebService error with .NET solution
我用 nuSOAP WebService 创建了一个 Laravel,它在除 .NET 解决方案之外的所有环境中都可以正常工作...
# PHP /app/Http/route.php
$app->group(['prefix' => 'test', 'namespace' => 'App\Http\Controllers'], function () use ($app) {
$app->get('/', 'TestController@index');
$app->get('/{any}', 'TestController@index');
$app->post('/', 'TestController@index');
$app->post('/{any}', 'TestController@index');
});
# PHP /app/Http/Controllers/TestController.php
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Common;
use SoapBox\Formatter\Formatter;
class TestController extends Controller
{
public function __construct()
{
$this->server = new \soap_server;
$end_point = env('END_POINT') . '/test/wsdl';
$this->server->configureWSDL('test', 'urn:test', $end_point, 'rpc');
$this->server->register(
'testMethod',
[
'one' => 'xsd:string',
'two' => 'xsd:string',
],
[
'return' => 'xsd:array'
],
'urn:testWSDL',
'urn:testWSDL#testMethod',
'rpc',
'encoded',
'Test Method'
);
}
function index(Request $request, $data = NULL)
{
$_SERVER['QUERY_STRING'] = '';
if ( $request->segment(2) == 'wsdl' ) $_SERVER['QUERY_STRING'] = 'wsdl';
return $this->server->service(file_get_contents('php://input'));
}
}
#PHP/app/Http/helpers.php
<?php use SoapBox\Formatter\Formatter;
function arrayToXml($array, $remove_structure = TRUE) {
$array = Formatter::make($array, Formatter::ARR);
$ret = $array->toXml();
if ( $remove_structure )
{
$ret = str_replace('<?xml version="1.0" encoding="utf-8"?>', '', $ret);
$ret = str_replace('<xml>', '', $ret);
$ret = str_replace('</xml>', '', $ret);
}
return trim($ret);
}
function testMethod($one, $two)
{
return arrayToXml([
"one" => $one,
"two" => $two
]);
}
如果我尝试使用 SoapGUI,我会发送:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:testWSDL">
<soapenv:Header/>
<soapenv:Body>
<urn:testMethod soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<one xsi:type="xsd:string">first</one>
<two xsi:type="xsd:string">second</two>
</urn:testMethod>
</soapenv:Body>
</soapenv:Envelope>
我收到...
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:testMethodResponse xmlns:ns1="urn:testWSDL">
<return xsi:type="xsd:array">
<one>first</one>
<two>second</two>
</return>
</ns1:testMethodResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
原始响应是:
HTTP/1.0 200 OK
Date: Tue, 02 Oct 2016 13:26:14 GMT
Server: Apache/2.4.18 (Unix) PHP/5.5.36 LibreSSL/2.2.7
X-Powered-By: PHP/5.5.36
X-SOAP-Server: NuSOAP/0.9.5 (1.56)
Content-Length: 537
Cache-Control: no-cache
Connection: close
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:testMethodResponse xmlns:ns1="urn:testWSDL"><return xsi:type="xsd:array"><one>first</one><two>second</two></return></ns1:testMethodResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
我在 soapclient.com/soaptest.html 中也尝试过并且工作得很好......
但在 .NET 解决方案中...我将其添加为 Web 参考:
然后添加下一个代码...我得到智能感知...
然后单击“单击我”按钮并出现此错误:
'System.InvalidOperationException' 类型的第一次机会异常发生在 System.Xml.dll
System.InvalidOperationException:文档错误 XML (1, 479)。 ---> System.InvalidCastException: No se puede asignar el objeto de tipo System.Xml.XmlNode[] al objeto de tipo System.String。
zh Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReadertest.Read2_testMethodResponse()
zh Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer3.Deserialize(XmlSerializationReader reader)
zh System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader、String encodingStyle、XmlDeserializationEvents 事件)
--- Fin del seguimiento de la pila de la excepción interna ---
zh System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader、String encodingStyle、XmlDeserializationEvents 事件)
zh System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
zh System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage 消息、WebResponse 响应、Stream responseStream、Boolean asyncCall)
zh System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
en testingSolution.local31.test.testMethod(String one, String two) en C:\Documents and Settings\admin\Mis documentos\testingSolution\Web References\local31\Reference.vb:línea 80
en testingSolution.Testeos.Button3_Click(Object sender, EventArgs e) en C:\Documents and Settings\admin\Mis documentos\testingSolution\index.vb:línea 50
如果我将 return 类型更改为字符串...在 .NET 解决方案中我得到:
但在 SoapGUI(以及所有其他应用程序)中:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:testMethodResponse xmlns:ns1="urn:testWSDL">
<return xsi:type="xsd:string"><one>mundo</one><two>aunque</two></return>
</ns1:testMethodResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我该怎么做才能解决这个问题?因为我需要 return 一个数组。谢谢!
最后就是这样:
// whether $methodreturn is a string of literal XML
$this->server->methodreturnisliteralxml = true;
来源:PHP NuSOAP response
我用 nuSOAP WebService 创建了一个 Laravel,它在除 .NET 解决方案之外的所有环境中都可以正常工作...
# PHP /app/Http/route.php
$app->group(['prefix' => 'test', 'namespace' => 'App\Http\Controllers'], function () use ($app) {
$app->get('/', 'TestController@index');
$app->get('/{any}', 'TestController@index');
$app->post('/', 'TestController@index');
$app->post('/{any}', 'TestController@index');
});
# PHP /app/Http/Controllers/TestController.php
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Common;
use SoapBox\Formatter\Formatter;
class TestController extends Controller
{
public function __construct()
{
$this->server = new \soap_server;
$end_point = env('END_POINT') . '/test/wsdl';
$this->server->configureWSDL('test', 'urn:test', $end_point, 'rpc');
$this->server->register(
'testMethod',
[
'one' => 'xsd:string',
'two' => 'xsd:string',
],
[
'return' => 'xsd:array'
],
'urn:testWSDL',
'urn:testWSDL#testMethod',
'rpc',
'encoded',
'Test Method'
);
}
function index(Request $request, $data = NULL)
{
$_SERVER['QUERY_STRING'] = '';
if ( $request->segment(2) == 'wsdl' ) $_SERVER['QUERY_STRING'] = 'wsdl';
return $this->server->service(file_get_contents('php://input'));
}
}
#PHP/app/Http/helpers.php
<?php use SoapBox\Formatter\Formatter;
function arrayToXml($array, $remove_structure = TRUE) {
$array = Formatter::make($array, Formatter::ARR);
$ret = $array->toXml();
if ( $remove_structure )
{
$ret = str_replace('<?xml version="1.0" encoding="utf-8"?>', '', $ret);
$ret = str_replace('<xml>', '', $ret);
$ret = str_replace('</xml>', '', $ret);
}
return trim($ret);
}
function testMethod($one, $two)
{
return arrayToXml([
"one" => $one,
"two" => $two
]);
}
如果我尝试使用 SoapGUI,我会发送:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:testWSDL">
<soapenv:Header/>
<soapenv:Body>
<urn:testMethod soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<one xsi:type="xsd:string">first</one>
<two xsi:type="xsd:string">second</two>
</urn:testMethod>
</soapenv:Body>
</soapenv:Envelope>
我收到...
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:testMethodResponse xmlns:ns1="urn:testWSDL">
<return xsi:type="xsd:array">
<one>first</one>
<two>second</two>
</return>
</ns1:testMethodResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
原始响应是:
HTTP/1.0 200 OK
Date: Tue, 02 Oct 2016 13:26:14 GMT
Server: Apache/2.4.18 (Unix) PHP/5.5.36 LibreSSL/2.2.7
X-Powered-By: PHP/5.5.36
X-SOAP-Server: NuSOAP/0.9.5 (1.56)
Content-Length: 537
Cache-Control: no-cache
Connection: close
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:testMethodResponse xmlns:ns1="urn:testWSDL"><return xsi:type="xsd:array"><one>first</one><two>second</two></return></ns1:testMethodResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
我在 soapclient.com/soaptest.html 中也尝试过并且工作得很好...... 但在 .NET 解决方案中...我将其添加为 Web 参考:
然后添加下一个代码...我得到智能感知...
然后单击“单击我”按钮并出现此错误:
'System.InvalidOperationException' 类型的第一次机会异常发生在 System.Xml.dll System.InvalidOperationException:文档错误 XML (1, 479)。 ---> System.InvalidCastException: No se puede asignar el objeto de tipo System.Xml.XmlNode[] al objeto de tipo System.String。 zh Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReadertest.Read2_testMethodResponse() zh Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer3.Deserialize(XmlSerializationReader reader) zh System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader、String encodingStyle、XmlDeserializationEvents 事件) --- Fin del seguimiento de la pila de la excepción interna --- zh System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader、String encodingStyle、XmlDeserializationEvents 事件) zh System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle) zh System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage 消息、WebResponse 响应、Stream responseStream、Boolean asyncCall) zh System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) en testingSolution.local31.test.testMethod(String one, String two) en C:\Documents and Settings\admin\Mis documentos\testingSolution\Web References\local31\Reference.vb:línea 80 en testingSolution.Testeos.Button3_Click(Object sender, EventArgs e) en C:\Documents and Settings\admin\Mis documentos\testingSolution\index.vb:línea 50
如果我将 return 类型更改为字符串...在 .NET 解决方案中我得到:
但在 SoapGUI(以及所有其他应用程序)中:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:testMethodResponse xmlns:ns1="urn:testWSDL">
<return xsi:type="xsd:string"><one>mundo</one><two>aunque</two></return>
</ns1:testMethodResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我该怎么做才能解决这个问题?因为我需要 return 一个数组。谢谢!
最后就是这样:
// whether $methodreturn is a string of literal XML
$this->server->methodreturnisliteralxml = true;
来源:PHP NuSOAP response