Supporting XSDs with attributes in WCF - c#

We have some XSDs in our project that define types that use attributes, as well as elements, to specify property values, e.g.:
<Instrument name="blah">
</Instrument>
I use these XSDs to define a schema used by a WSDL, but when I run it through schemagen, the generated code is unwrapped. For example:
public interface InstrumentService
{
// CODEGEN: Parameter 'GetInstrumentResponse' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlElementAttribute'.
GetInstrumentResponse GetInstrument(GetInstrumentRequest request);
}
(the GetInstrumentRequest and GetInstrumentResponse should be unwrapped to the parameters and return value only).
The reason for this is that the data contract serializer doesn't support complex types with attributes, but I did read somewhere that if you use document/literal, rather than document/literal wrapped to define the WSDL, schemagen will fall back to an XmlSerializer implementation, that does support attributes. So far, my attempts to get this to work have failed:
// CODEGEN: Generating message contract since the operation GetInstrument is neither RPC nor document wrapped.
So, is this assumption about document/literal faulty? Is there any way to generate unwrapped interface code from a WSDL that defines complex types with attributes?
Here's the modified document/literal WSDL I am using:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
targetNamespace="http://tempuri.org/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:tns="http://tempuri.org/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xs:schema targetNamespace="http://tempuri.org/">
<xs:complexType name="testComplexType">
<xs:sequence/>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:element name="input" type="tns:testComplexType"/>
</xs:schema>
</wsdl:types>
<wsdl:message name="GetInstrumentIn">
<wsdl:part element="tns:input" name="input"/>
</wsdl:message>
<wsdl:message name="GetInstrumentOut"/>
<wsdl:portType name="InstrumentService">
<wsdl:operation name="GetInstrument">
<wsdl:input message="tns:GetInstrumentIn"/>
<wsdl:output message="tns:GetInstrumentOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="InstrumentService" type="tns:InstrumentService">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetInstrument">
<soap:operation soapAction="GetInstrument" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="InstrumentService">
<wsdl:port binding="tns:InstrumentService" name="InstrumentService"/>
</wsdl:service>
</wsdl:definitions>

apologies for answering my own question. It seems that just removing the nillable="true" statement from the operation response type, in th document/literal/wrapped WSDL types schema does the trick - no need to drop to document/literal.
<wsdl:types>
<xs:schema elementFormDefault="qualified" targetNamespace="http://com.barcap.cbts.core.messaging.rpc/">
<xs:element name="GetInstrument">
<xs:complexType/>
</xs:element>
<xs:element name="GetInstrumentResponse">
<xs:complexType>
<xs:sequence>
<!-- nillable="true" removed -->
<xs:element maxOccurs="1" minOccurs="0"
name="GetInstrumentResponse" type="tns:Instrument"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="Instrument">
<xs:sequence/>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
</xs:schema>
</wsdl:types>

Related

How to return an XML with node-soap server?

I'm making a NodeJS web service that contains API REST and SOAP methods (Im using https://www.npmjs.com/package/soap) with Express. With API REST I don't have any problem but with SOAP I have an inconvenient, when I try to consume the SOAP method from a testing C# application I can see that the parameters are going fine, but in the response I have the next error in C# (Response is not correct XML code)
When I consume the method from a NodeJS client with node-soap too the response working fine.
Part of my NodeJS code:
const express = require('express');
const bodyParser = require('body-parser');
const soap = require('soap');
const fs = require('fs');
const xml = fs.readFileSync('src/templates/ws_soap.wsdl', 'utf8');
const app = express();
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
const soap_service = {
integrations: {
pull: {
getSnapshotGIGA: function(args) {
return {
res: "HOLA"
};
},
}
}
};
app.listen(port, ip, function() {
soap.listen(app, '/integrations_service', soap_service, xml, function() {
console.log('SOAP web service started on ' + ip + ':' + port);
});
console.log('API REST started on ' + ip + ':' + port);
});
My WSDL file is next (In response I have the type string because I wanted to see how it behaved, but I need to return an object XML):
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="integrations_service" targetNamespace="http://localhost:4205/integrations_service" xmlns="http://localhost:4205/integrations_service" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<wsdl:message name="getSnapshotGIGARequest">
<wsdl:part name="User" type="xs:string"/>
<wsdl:part name="Password" type="xs:string"/>
</wsdl:message>
<wsdl:message name="getSnapshotGIGAResponse">
<wsdl:part name="res" type="xs:string"/>
</wsdl:message>
<wsdl:portType name="pull_integrations">
<wsdl:operation name="getSnapshotGIGA">
<wsdl:input message="getSnapshotGIGARequest"/>
<wsdl:output message="getSnapshotGIGAResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="pull_integrations_binding" type="pull_integrations">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getSnapshotGIGA">
<soap:operation soapAction="getSnapshotGIGA"/>
<wsdl:input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="integrations">
<wsdl:port binding="pull_integrations_binding" name="pull">
<soap:address location="http://localhost:4205/integrations_service"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
In C# I have an console application and I have registered the SOAP service as a web referency.
The way I consume the SOAP method is (When I make a SOAP Service with C# I test methods from this way too because is the way clients working):
Console.WriteLine("Consume NodeJS SOAP service");
Thread.Sleep(500);
integrations_service.integrations integrations = new integrations_service.integrations();
integrations.Url = "http://localhost:4205/integrations_service?wsdl";
var some_response = integrations.getSnapshotGIGA("myuser", "123456");
Console.WriteLine("Press enter to out...");
I want to get the response in and XmlNode like in this example:
Console.WriteLine("Consume C# SOAP service");
Thread.Sleep(500);
serviceSOAP sSOAP = new serviceSOAP ();
sSOAP.Url = "http://my.domain.com.mx/";
XmlNode xmlNode = sSOAP .anyMethodSoap("yomero", "123456");
Console.WriteLine(XElement.Parse(xmlNode.OuterXml).ToString());
Thread.Sleep(500);
If you know how I can return the XML from NodeJS and get it correctly in C# or any idea, I would appreciate it. Reggards.
Answer to my question, the problem was the WSDL configuration. With this configuration I made this works with C# web reference. The principal problem, the style, I changed it from "rpc" to "document" and configure correctly the element for the response.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
name="devices_service"
targetNamespace="http://localhost:4205/devices_service"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:s="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://localhost:4205/devices_service">
<wsdl:types>
<xs:schema targetNamespace="http://localhost:4205/devices_service" xmlns="http://localhost:4205/devices_service" attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="GetDevicesRequest">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="User" type="xs:string"/>
<xs:element minOccurs="0" maxOccurs="1" name="Password" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetDevicesResponse">
<xs:complexType>
<xs:sequence>
<xs:any/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="GetDevicesSoapIn">
<wsdl:part name="parameters" element="GetDevicesRequest"/>
</wsdl:message>
<wsdl:message name="GetDevicesSoapOut">
<wsdl:part name="parameters" element="GetDevicesResponse"/>
</wsdl:message>
<wsdl:portType name="user_devices">
<wsdl:operation name="GetDevices">
<wsdl:input message="GetDevicesSoapIn"/>
<wsdl:output message="GetDevicesSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="user_devices_binding" type="user_devices">
<s:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
<wsdl:operation name="GetDevices">
<s:operation soapAction="http://localhost:4205/devices_services/GetDevices"/>
<wsdl:input>
<s:body use="literal" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</wsdl:input>
<wsdl:output>
<s:body use="literal" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="devices">
<wsdl:port binding="user_devices_binding" name="user">
<s:address location="http://localhost:4205/devices_service"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>**
You'll probably want to use one of:
node-soap
strong-soap (rewrite of node-soap)
easysoap

Why are the parameters of the ASMX Proxy Methods capsulated?

I am adding a Service Reference to a Third-Party-ASMX Webservice in my VS2015 or VS2017 Project (Net 4.6.1).
I do this with the normal Userinterface in Visual Studio (Rightclick --> Add new Service Reference). I use the default settings and everything seems to work except that i am not happy with the generated classes.
According to the WSDL i am expecting to use the methods like this:
ServiceSoapClient ssc = new ServiceSoapClient();
object response = ssc.getEmployees("xxx", "yyy", "zzz");
But what i get is classes that i have to use like this:
ServiceSoapClient ssc = new ServiceSoapClient();
getEmployeesResponse response = ssc.getEmployees(
new getEmployeesRequest
{
Body = new getEmployeesRequestBody { Division = "xxx", Username = "yyy", Password = "zzz" }
});
Every Method needs one Request-Parameter, which itself has a Body-Element. The Body-Element has all the necessary Parameters.
The Method is defined like that when opened in the browser:
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getEmployees xmlns="xxx">
<division>string</division>
<Username>string</Username>
<Password>string</Password>
</getEmployees>
</soap:Body>
</soap:Envelope>
That is the information for this Method in the WSDL:
<s:element name="getEmployees">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="division" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Username" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Password" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="getEmployeesResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="getEmployeesResult" type="tns:XMLResponse"/>
</s:sequence>
</s:complexType>
</s:element>
<wsdl:operation name="getEmployees">
<wsdl:input message="tns:getEmployeesSoapIn"/>
<wsdl:output message="tns:getEmployeesSoapOut"/>
</wsdl:operation>
<wsdl:operation name="getEmployees">
<soap:operation soapAction="http://xxx/getEmployees" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
Why do i not get a method with the three parameters of type string? Am i even able to control this on client-side or is there a common mistake?
When i provide the Webservices by myself or use other services i never had this problem before.
I found the reason. In the settings of the "Service Reference" you have to activate "Generate assynchronous operations".

How to consume a wsdl file that doesn't exist on web in C#

I am trying to impliment a service with SOAP messages to my visual studio project.
They gave me some instructions and I saw on stackoverflow that I have to consume the wsdl and xsd file in visual studio so that it can create all the classes that I need.
The problem is that when I try to add the wsdl file as service reference it says that the file doesnt exist. I search it myself using the URL provided and it really doesnt exists.
Is there any way so that I can use it.
Below is the WSDL statement:
https://www1.gsis.gr/wsicispay/rmt_ws?wsdl
<definitions targetNamespace="http://remittance_ws/rmt_ws.wsdl" name="rmt_ws"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://remittance_ws/rmt_ws.wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xsd:schema>
<xsd:import namespace="http://remittance_ws/rmt_ws.wsdl"
schemaLocation="https://www1.gsis.gr/wsicispay/rmt_ws?xsd=1"/>
</xsd:schema>
</types>
<message name="remittanceXml">
<part name="parameters" element="tns:remittanceXml"/>
</message>
<message name="remittanceXmlResponse">
<part name="parameters" element="tns:remittanceXmlResponse"/>
</message>
<message name="UnsupportedEncodingException">
<part name="fault" element="tns:UnsupportedEncodingException"/>
</message>
<portType name="rmt_ws">
<operation name="remittanceXml">
<input message="tns:remittanceXml"/>
<output message="tns:remittanceXmlResponse"/>
<fault message="tns:UnsupportedEncodingException" name="UnsupportedEncodingException"/>
</operation>
</portType>
<binding name="rmt_wsBinding" type="tns:rmt_ws">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="remittanceXml">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="UnsupportedEncodingException">
<soap:fault name="UnsupportedEncodingException" use="literal"/>
</fault>
</operation>
</binding>
<service name="rmt_ws">
<port name="rmt_ws" binding="tns:rmt_wsBinding">
<soap:address location="https://www1.gsis.gr/wsicispay/rmt_ws"/>
</port>
</service>
</definitions>
and here is the xsd
https://www1.gsis.gr/wsicispay/rmt_ws?xsd=1
<xs:schema version="1.0" targetNamespace="http://remittance_ws/rmt_ws.wsdl"
xmlns:tns="http://remittance_ws/rmt_ws.wsdl" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="UnsupportedEncodingException" type="tns:UnsupportedEncodingException"/>
<xs:element name="remittanceXml" type="tns:remittanceXml"/>
<xs:element name="remittanceXmlResponse" type="tns:remittanceXmlResponse"/>
<xs:complexType name="remittanceXml">
<xs:sequence>
<xs:element name="inputXML" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="remittanceXmlResponse">
<xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="UnsupportedEncodingException">
<xs:sequence>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Δείγμα μηνύματος:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:rmt="http://remittance_ws/rmt_ws.wsdl">
<soapenv:Header/>
<soapenv:Body>
<rmt:remittanceXml>
<inputXML><remittance><wsTin>Tin</wsTin><wsUser>Username</wsUser><wsPswd
>Pswd</wsPswd><contain><bmrn>16GRIMXXXX00001746</bmrn><blrn>TESTFOR1&
lt;/blrn><bcnt>1</bcnt><bafm>099099099</bafm></contain><contain><bmr
n>16GRIMXXXX00001720</bmrn><blrn>TESTFOR2</blrn><bcnt>2</bcnt><bafm&
gt;099099099</bafm></contain><contain><bmrn>16GRIMXXXX00001738</bmrn><bl
rn>TESTFOR2</blrn><bcnt>2</bcnt><bafm>099099099</bafm></contain></
remittance></inputXML>
</rmt:remittanceXml>
</soapenv:Body>
</soapenv:Envelope>
Those are in a pdf file that they gave me.
EDIT:
If I add it as a file from service references it creates the reference ePayments and no .cs file.
When I add the reference it gives me only one service rmt_ws which has an operation remitanceXML and nothing else.
I don't know if this is correct and how should I use it
I copied the xsd part into the wsdl and visual studio generates a service with one operation to send an input XML and return another XML. I hope, this helps.
rmt_ws.wsdl:
<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://remittance_ws/rmt_ws.wsdl" name="rmt_ws" targetNamespace="http://remittance_ws/rmt_ws.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xs:schema targetNamespace="http://remittance_ws/rmt_ws.wsdl" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="UnsupportedEncodingException" type="tns:UnsupportedEncodingException" />
<xs:element name="remittanceXml" type="tns:remittanceXml" />
<xs:element name="remittanceXmlResponse" type="tns:remittanceXmlResponse" />
<xs:complexType name="remittanceXml">
<xs:sequence>
<xs:element minOccurs="0" name="inputXML" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="remittanceXmlResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="UnsupportedEncodingException">
<xs:sequence>
<xs:element minOccurs="0" name="message" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</types>
<message name="remittanceXml">
<part name="parameters" element="tns:remittanceXml" />
</message>
<message name="remittanceXmlResponse">
<part name="parameters" element="tns:remittanceXmlResponse" />
</message>
<message name="UnsupportedEncodingException">
<part name="fault" element="tns:UnsupportedEncodingException" />
</message>
<portType name="rmt_ws">
<operation name="remittanceXml">
<input message="tns:remittanceXml" />
<output message="tns:remittanceXmlResponse" />
<fault name="UnsupportedEncodingException" message="tns:UnsupportedEncodingException" />
</operation>
</portType>
<binding name="rmt_wsBinding" type="tns:rmt_ws">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="remittanceXml">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
<fault name="UnsupportedEncodingException">
<soap:fault use="literal" name="UnsupportedEncodingException" namespace="" />
</fault>
</operation>
</binding>
<service name="rmt_ws">
<port name="rmt_ws" binding="tns:rmt_wsBinding">
<soap:address location="https://www1.gsis.gr/wsicispay/rmt_ws" />
</port>
</service>
</definitions>
I remember, that I had a problem with authentication of a web service some years ago, but I didn't remember where I found this alternative solution:
Create a new console app in visual studio (I am not sure, if deleting the old service reference in the existing project works without manual editing project file etc.)
Select add service reference as before, but don't enter the path of a wsdl. Instead press the button "Advanced..." in the dialog and "Add Web reference..." in the next dialog.
In the new dialog enter the path of the wsdl file and press "Add reference"
Open the file "program.cs" in the project and add this class with namespace between the last "using..." line and "namespace...."
namespace TestWeb.WebReference
{
partial class rmt_ws : System.Web.Services.Protocols.SoapHttpClientProtocol {
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.HttpWebRequest request;
request = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
if (PreAuthenticate) {
System.Net.NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null) {
System.Diagnostics.Debug.WriteLine("User: " + networkCredentials.UserName);
System.Diagnostics.Debug.WriteLine("PW: " + networkCredentials.Password);
byte[] credentialBuffer = new UTF8Encoding().GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password);
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
}
else {
throw new ApplicationException("No network credentials");
}
}
return request;
}
}
Replace "TestWeb" (first line of inserted code) with the namespace of your project (normally the project name).
Replace the existing class "Program" with the following code:
class Program {
static void Main(string[] args) {
// Fill with a valid xml request
String inputXML = "";
String answer = "";
try {
WebReference.rmt_ws _webService = new WebReference.rmt_ws();
System.Net.CredentialCache myCredentials = new System.Net.CredentialCache();
// Set correct user and password
System.Net.NetworkCredential netCred = new System.Net.NetworkCredential("User", "Password");
_webService.Credentials = netCred.GetCredential(new Uri(_webService.Url), "Basic");
_webService.PreAuthenticate = true;
answer = _webService.remittanceXml(inputXML);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.WriteLine(answer);
Console.ReadLine();
}
}
Set inputXML with a valid xml for your request
Set the correct user and password
If this does not help you should really open a new question to find some one other who could help.
I contact again for the communication problem and they send me this xml
<?xml version="1.0" encoding="UTF-8"?>
<con:soapui-project id="6026c0c2-d6a6-487f-8551-c5f616d5efab" xmlns:con="http://eviware.com/soapui/config" runType="SEQUENTIAL" abortOnError="false" soapui-version="5.2.1" resourceRoot="" name="pre-prod" activeEnvironment="Default">
<con:settings/>
<con:interface id="dba85261-52fb-48a6-96c0-9fcedc1e8146" name="rmt_wsBinding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" definition="https://www1.gsis.gr/wsicispay/rmt_ws?wsdl" anonymous="optional" soapVersion="1_1" bindingName="{http://remittance_ws/rmt_ws.wsdl}rmt_wsBinding" type="wsdl" xsi:type="con:WsdlInterface" wsaVersion="NONE">
<con:settings/>
<con:definitionCache type="TEXT" rootPart="https://www1.gsis.gr/wsicispay/rmt_ws?wsdl">
<con:part>
<con:url>https://www1.gsis.gr/wsicispay/rmt_ws?wsdl</con:url>
<con:content>
<![CDATA[
<!--Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Oracle JAX-WS 2.1.5.-->
<!--Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Oracle JAX-WS 2.1.5.-->
<definitions targetNamespace="http://remittance_ws/rmt_ws.wsdl" name="rmt_ws" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://remittance_ws/rmt_ws.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xsd:schema>
<xsd:import namespace="http://remittance_ws/rmt_ws.wsdl" schemaLocation="https://www1.gsis.gr/wsicispay/rmt_ws?xsd=1"/>
</xsd:schema>
</types>
<message name="remittanceXml">
<part name="parameters" element="tns:remittanceXml"/>
</message>
<message name="remittanceXmlResponse">
<part name="parameters" element="tns:remittanceXmlResponse"/>
</message>
<message name="UnsupportedEncodingException">
<part name="fault" element="tns:UnsupportedEncodingException"/>
</message>
<portType name="rmt_ws">
<operation name="remittanceXml">
<input message="tns:remittanceXml"/>
<output message="tns:remittanceXmlResponse"/>
<fault message="tns:UnsupportedEncodingException" name="UnsupportedEncodingException"/>
</operation>
</portType>
<binding name="rmt_wsBinding" type="tns:rmt_ws">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="remittanceXml">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="UnsupportedEncodingException">
<soap:fault name="UnsupportedEncodingException" use="literal"/>
</fault>
</operation>
</binding>
<service name="rmt_ws">
<port name="rmt_ws" binding="tns:rmt_wsBinding">
<soap:address location="https://www1.gsis.gr/wsicispay/rmt_ws"/>
</port>
</service>
</definitions>
]]>
</con:content>
<con:type>http://schemas.xmlsoap.org/wsdl/</con:type>
</con:part>
<con:part>
<con:url>https://www1.gsis.gr/wsicispay/rmt_ws?xsd=1</con:url>
<con:content>
<![CDATA[
<!--Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Oracle JAX-WS 2.1.5.-->
<xs:schema version="1.0" targetNamespace="http://remittance_ws/rmt_ws.wsdl" xmlns:tns="http://remittance_ws/rmt_ws.wsdl" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="UnsupportedEncodingException" type="tns:UnsupportedEncodingException"/>
<xs:element name="remittanceXml" type="tns:remittanceXml"/>
<xs:element name="remittanceXmlResponse" type="tns:remittanceXmlResponse"/>
<xs:complexType name="remittanceXml">
<xs:sequence>
<xs:element name="inputXML" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="remittanceXmlResponse">
<xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="UnsupportedEncodingException">
<xs:sequence>
<xs:element name="message" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
]]>
</con:content>
<con:type>http://www.w3.org/2001/XMLSchema</con:type>
</con:part>
</con:definitionCache>
<con:endpoints>
<con:endpoint>https://www1.gsis.gr/wsicispay/rmt_ws</con:endpoint>
</con:endpoints>
<con:operation id="432ec623-b52f-49b6-bff5-ff220d2dc4e8" name="remittanceXml" anonymous="optional" type="Request-Response" sendsAttachments="false" receivesAttachments="false" inputName="" bindingOperationName="remittanceXml" action="" isOneWay="false">
<con:settings/>
<con:call id="84ad3fc8-b5a2-491b-b375-8fc6d8b5edb4" name="Request 1">
<con:settings>
<con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest#request-headers"><xml-fragment/></con:setting>
</con:settings>
<con:encoding>UTF-8</con:encoding>
<con:endpoint>https://www1.gsis.gr/wsicispay/rmt_ws</con:endpoint>
<con:request>
<![CDATA[]]>
</con:request>
<con:credentials>
<con:USERNAME>USERNAME</con:USERNAME>
<con:PASSWORD>PASSWORD</con:PASSWORD>
<con:username>USERNAME</con:username>
<con:password>PASSWORD</con:password>
<con:selectedAuthProfile>Basic</con:selectedAuthProfile>
<con:addedBasicAuthenticationTypes>Basic</con:addedBasicAuthenticationTypes>
<con:authType>Global HTTP Settings</con:authType>
</con:credentials>
<con:jmsConfig JMSDeliveryMode="PERSISTENT"/>
<con:jmsPropertyConfig/>
<con:wsaConfig action="http://remittance_ws/rmt_ws.wsdl/rmt_ws/remittanceXmlRequest" version="200508" mustUnderstand="NONE"/>
<con:wsrmConfig version="1.2"/>
</con:call>
</con:operation>
</con:interface>
<con:properties/>
<con:wssContainer/>
<con:oAuth2ProfileContainer/>
</con:soapui-project>
Can I use this file in visual studio ? Is this better for the previous?

Creating a Web Service consumer from a WSDL with nested complex types

I am trying to create a web service consumer, given a WSDL of a service that is already up and running. The challenge is, doing the whole thing dynamically, in runtime. I am working with C#. To sum up, I have to do the following:
I have an application that will be given as input the WSDL file (url). done
The application will drill down the WSDL file, recognizing the operations, messages and the types used. (point that I'm having trouble with)
It will create the code needed to invoke the Web Service, compile it and load it through reflection. done
Have everything ready for invocation, including creating and sending the necessary parameters to the remote method. Then it'll handle the response properly. done
I am having some issues with #2, which is parsing and drilling down in the WSDL file. In specific: extracting complex types that appear to be "nested".
I've read some very useful resources about extracting complex types:
Parse Complex WSDL Parameter Information
Detailed ServiceDescription / Proxy from WSDL
http://mikehadlow.blogspot.com/2006/06/simple-wsdl-object.html
However, I am a bit puzzled with an example WSDL that I have received for testing:
<definitions name='MyWSService' targetNamespace='http://some.url.com/' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://some.url.com/' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<types>
<xs:schema attributeFormDefault='qualified' elementFormDefault='qualified' targetNamespace='http://some.url.com/' version='1.0' xmlns:tns='http://some.url.com/' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<xs:element name='dsSendOperationName' type='tns:systemSendOperationName'/>
<xs:element name='dsSendOperationNameResponse' type='tns:systemSendOperationNameResponse'/>
<xs:complexType name='systemSendOperationName'>
<xs:sequence>
<xs:element minOccurs='0' name='systemOperationName' type='tns:systemOperationName'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='systemOperationName'>
<xs:sequence>
<xs:element minOccurs='0' name='param1' type='xs:string'/>
<xs:element minOccurs='0' name='param2' type='xs:string'/>
<xs:element minOccurs='0' name='param3' type='xs:string'/>
<xs:element minOccurs='0' name='param4' type='xs:string'/>
<xs:element minOccurs='0' name='param5' type='xs:string'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='systemSendOperationNameResponse'>
<xs:sequence>
<xs:element minOccurs='0' name='return' type='xs:string'/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</types>
<message name='SystemOperationNameWS_dsSendOperationName'>
<part element='tns:dsSendOperationName' name='dsSendOperationName'></part>
</message>
<message name='SystemOperationNameWS_dsSendOperationNameResponse'>
<part element='tns:dsSendOperationNameResponse' name='dsSendOperationNameResponse'></part>
</message>
<portType name='SystemOperationNameWS'>
<operation name='dsSendOperationName' parameterOrder='dsSendOperationName'>
<input message='tns:SystemOperationNameWS_dsSendOperationName'></input>
<output message='tns:SystemOperationNameWS_dsSendOperationNameResponse'></output>
</operation>
</portType>
<binding name='SystemOperationNameWSBinding' type='tns:SystemOperationNameWS'>
<soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='dsSendOperationName'>
<soap:operation soapAction=''/>
<input>
<soap:body use='literal'/>
</input>
<output>
<soap:body use='literal'/>
</output>
</operation>
</binding>
<service name='SystemOperationNameWSService'>
<port binding='tns:SystemOperationNameWSBinding' name='SystemOperationNameWSPort'>
<soap:address location='http://a.url.here.com'/>
</port>
</service>
</definitions>
Look how the root elements (as defined in the messages' section) are referring to a complex type, which has an element that is later on declared as a complex type, that finally has a sequence of elements with standard XSD types.
Programatically, I am able to drill down to the very last element of that "chain". However, I am confused about the type of the actual message being sent to the web service. Is it:
A systemSendOperationName that wraps a systemOperationName, that contains 5 strings?
or
A systemOperationName object that contains 5 strings?
And overall, is that sort of nested types normal? I haven't found a similar example so far.
EDIT:
Made some points of my initial post more clear to avoid any confusions.

Not showing data from SOAP service

I have an interesting problem involving a C# console client and a web service.
My suspicion is that there is a name space error somewhere or something simple, but eight hours of staring blankly into the screen has yet to reveal them so I thought I'd try a few more eyes.
WSDL
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://
schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:schema="http://xxx.com/BillOfMaterials/schemas" xmlns:tns="http://
xxx.com/BillOfMaterials/definitions"
targetNamespace="http://xxx.com/BillOfMaterials/definitions">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://xxx.com/BillOfMaterials/
schemas" schemaLocation="BOMRequest.xsd" id="input"/>
<xs:import namespace="http://xxx.com/BillOfMaterials/schemas"
schemaLocation="BOMResponse.xsd" id="output"/>
</xs:schema>
</wsdl:types>
<wsdl:message name="BomRequest">
<wsdl:part name="input" element="schema:BOMin"/>
</wsdl:message>
<wsdl:message name="BomResponse">
<wsdl:part name="output" element="schema:BOMResponse"/>
</wsdl:message>
<wsdl:portType name="BOMPortType">
<wsdl:operation name="BOM">
<wsdl:input message="tns:BomRequest"/>
<wsdl:output message="tns:BomResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BOMBinding" type="tns:BOMPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/
http"/>
<wsdl:operation name="BOM">
<soap:operation soapAction="urn:#BOMOperation"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="BOMService">
<wsdl:port name="BOMPort" binding="tns:BOMBinding">
<soap:address location="http://xxx/BOM"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Request XSD
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/
XMLSchema" xmlns:in="http://secotools.com/BillOfMaterials/schemas"
targetNamespace="http://xxx.com/BillOfMaterials/schemas" elementFormDefault="qualified">
<xs:element name="BOMin" type="in:BOMRequestItem"/>
<xs:complexType name="BOMRequestItem">
<xs:sequence>
<xs:element name="ProductNumber" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Response XSD (shortened as it's well large)
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/
XMLSchema" xmlns:in="http://xxx.com/BillOfMaterials/schemas"
targetNamespace="http://xxx.com/BillOfMaterials/schemas"
elementFormDefault="qualified">
<xs:element name="BOMResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="BOMResponses" type="in:BOMResponseItem"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="BOMResponseItem">
<xs:sequence>
<xs:element name="Company" type="xs:string"/>
<xs:element name="Facility" type="xs:string"/>
<xs:element name="ProductNumber" type="xs:string"/>
<xs:element name="ProductStructureType" type="xs:string"/>
<xs:element name="Name" type="xs:string"/>
Using this WSDL I get the following request and response in soapUI:
SoapUI request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sch="http://xxx.com/BillOfMaterials/schemas">
<soapenv:Header/>
<soapenv:Body>
<sch:BOMin>
<ProductNumber>12345</ProductNumber>
</sch:BOMin>
</soapenv:Body>
</soapenv:Envelope>
SoapUI response (shortened for readability):
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:out="http://xxx.com/BillOfMaterials/schemas">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<out:BOMResponse>
<Company>1</Company>
<Facility>1</Facility>
<ProductNumber>12345</ProductNumber>
<ProductStructureType>PLU</ProductStructureType>
<Name>My dummy product</Name>
I've tried both generating a proxy with svcutil and used a service reference in C# to no avail. SoapUI works as expected and returns data while C# get an empty list.
C# test code
class Program
{
static void Main(string[] args)
{
BOMPortTypeClient _client = new BOMPortTypeClient();
var state = _client.State;
BOMRequestItem _reqItem = new BOMRequestItem
{
ProductNumber = "12345"
};
IList<BOMResponseItem> _list = _client.BOM(_reqItem);
}
}
Edit: Added Fiddler logs with request/response from .Net
.Net request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<BOMin xmlns="http://xxx.com/BillOfMaterials/schemas">
<ProductNumber>12345</ProductNumber>
</BOMin>
</s:Body>
</s:Envelope>
.Net response
<?xml version="1.0" ?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://xxx.com/BillOfMaterials/schemas" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Header/>
<s:Body>
<BOMResponse>
<Company>1</Company>
<Facility>1</Facility>
<ProductNumber>12345</ProductNumber>
<ProductStructureType>PLU</ProductStructureType>
<Name>My dummy product</Name>
Since I do get data back I know the service understands the request from .Net, problem is .Net seems unable to understand the response. This is why I thought at first it was a namespace issue. Now I'm not so sure anymore. I get no errors in .Net, just an empty array.

Categories

Resources