JAXB Eclipse Link Moxy: ClassCastException while Unmarshalling JSON using schema validation - eclipselink

I am using eclipse link(v2.5.1) Dynamic JAXB to convert XML to JSON and viceversa using a multiple schemas. While umarshalling the JSON to XML,I want to validate the JSON(against the XSD) and Dynamic Moxy is unable to validate the generated JSON and results in classcast exception.
emp.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:emp="Employee:2:0" targetNamespace="Employee:2:0"
elementFormDefault="unqualified" attributeFormDefault="unqualified"
version="2.0">
<xsd:element name="searchManager" type="emp:SearchManager" />
<xsd:complexType name="SearchManager">
<xsd:sequence>
<xsd:element name="CompanyName" type="xsd:string" />
<xsd:element name="objects" type="emp:Employee" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Employee">
<xsd:complexContent>
<xsd:extension base="emp:Organization">
<xsd:sequence>
<xsd:element name="EmpId" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Projects">
<xsd:complexContent>
<xsd:extension base="emp:Organization"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Organization">
<xsd:annotation>
<xsd:documentation>Abstract base class </xsd:documentation>
</xsd:annotation>
</xsd:complexType>
</xsd:schema>
Manager.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="Manager:1:0" xmlns:emp="Employee:2:0"
xmlns:manager="Manager:1:0" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified" attributeFormDefault="unqualified"
version="1.0">
<!-- schema imports -->
<xs:import namespace="Employee:2:0" schemaLocation="emp.xsd" />
<xs:complexType name="Manager">
<xs:annotation>
<xs:documentation>
Definition of class Employee
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="emp:Employee">
<xs:sequence>
<xs:element name="teamSize" type="xsd:int" minOccurs="0" />
<xs:element name="project1" type="manager:Project1"
minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Project1">
<xs:complexContent>
<xs:extension base="manager:Developement">
<xs:sequence>
<xs:element name="type" type="xsd:int" minOccurs="0" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Developement">
<xs:annotation>
<xs:documentation>
Abstract base class for an Development
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="emp:Projects"/>
</xs:complexContent>
</xs:complexType>
</xs:schema>
sample.xml
<emp:searchManager xmlns:emp="Employee:2:0"
xmlns:manager="Manager:1:0">
<CompanyName>Test</CompanyName>
<objects xmlns:ns2="Manager:1:0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:Manager">
<EmpId>123456</EmpId>
<teamSize>10</teamSize>
<project1>
<type>1</type>
</project1>
</objects>
</emp:searchManager>
The driver program to test is as follows
public class XMLToJSON {
/**
* #param args
*/
public static void main(String[] args) {
FileInputStream xsdInputStream;
try {
xsdInputStream = new FileInputStream("Manager.xsd");
DynamicJAXBContext jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, new MyEntityResolver(), null, null);
FileInputStream xmlInputStream = new FileInputStream("sample.xml");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement<DynamicEntity> manager = (JAXBElement) unmarshaller.unmarshal(xmlInputStream);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//input xml to print
marshaller.marshal(manager, System.out);
Map namespaces = new HashMap();
namespaces.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
namespaces.put("Employee:2:0", "ns1");
namespaces.put("Manager:1:0", "ns2");
// XML to JSON
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaces);
FileOutputStream jsonOutputStream = new FileOutputStream("sample.json");
marshaller.marshal(manager, jsonOutputStream);
marshaller.marshal(manager, System.out);
//JSON to XML
JAXBUnmarshaller jsonUnmarshaller = jaxbContext.createUnmarshaller();
jsonUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespaces);
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, true);
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX, "#");
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("Manager.xsd"));
jsonUnmarshaller.setSchema(schema);
StreamSource json = new StreamSource("sample.json");
JAXBElement<DynamicEntity> myroot = (JAXBElement) jsonUnmarshaller.unmarshal(json);
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
m.marshal(myroot, System.out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Generated Sample JSON
{
"ns1.searchManager" : {
"CompanyName" : "Test",
"objects" : [ {
"xsi.type" : "ns2.Manager",
"EmpId" : "123456",
"teamSize" : 10,
"project1" : [ {
"type" : 1
} ]
} ]
}
}
While unmarshalling the below exception was seen
Exception in thread "main" java.lang.ClassCastException: org.eclipse.persistence.internal.oxm.record.XMLReaderAdapter$ExtendedContentHandlerAdapter cannot be cast to org.eclipse.persistence.internal.oxm.record.UnmarshalRecord
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.isTextValue(JSONReader.java:454)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:350)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:244)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:430)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:299)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:166)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:140)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:778)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:666)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:593)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:287)
at XMLToJSON.main(XMLToJSON.java:74)
EDIT:Corrected the generated sample json
Question
The intention is to check whether JSON conforms to the XML schema. Does Dynamic JAXB support JSON Validation while unmarshalling? Is this a bug in Dynamic JAXB Moxy?

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
You are hitting the following issue which was fixed in the 2.5.1 (and 2.6.0) streams.
http://bugs.eclipse.org/407498
The fix is available in EclipseLink 2.5.1 (and 2.6.0) in the nightly builds starting September 11, 2013 from the following link:
http://www.eclipse.org/eclipselink/downloads/nightly.php
Schema Validation and JSON Unmarshalling
Due to how we need to process the JSON document, validating the JSON input against an XML schema is not guaranteed to work. Below is the exception you will get for your use case once you get the ClassCastException fix.
javax.xml.bind.UnmarshalException
- with linked exception:
[Exception [EclipseLink-25004] (Eclipse Persistence Services - #VERSION#.#QUALIFIER#): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred unmarshalling the document
Internal Exception: org.xml.sax.SAXParseException; cvc-complex-type.2.4.d: Invalid content was found starting with element 'teamSize'. No child element is expected at this point.]
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:980)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:290)
at forum18824990.XMLToJSON.main(XMLToJSON.java:63)
Caused by: Exception [EclipseLink-25004] (Eclipse Persistence Services - #VERSION#.#QUALIFIER#): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred unmarshalling the document
Internal Exception: org.xml.sax.SAXParseException; cvc-complex-type.2.4.d: Invalid content was found starting with element 'teamSize'. No child element is expected at this point.
at org.eclipse.persistence.exceptions.XMLMarshalException.unmarshalException(XMLMarshalException.java:115)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:144)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:784)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:666)
at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:566)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:287)
... 1 more
Caused by: org.xml.sax.SAXParseException; cvc-complex-type.2.4.d: Invalid content was found starting with element 'teamSize'. No child element is expected at this point.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:325)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:453)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3232)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1795)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:741)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(ValidatorHandlerImpl.java:565)
at org.eclipse.persistence.internal.oxm.record.XMLReader$ValidatingContentHandler.startElement(XMLReader.java:431)
at org.eclipse.persistence.internal.oxm.record.XMLReaderAdapter$ExtendedContentHandlerAdapter.startElement(XMLReaderAdapter.java:178)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:302)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:436)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:418)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:244)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:436)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:303)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:166)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:140)
... 5 more

Related

.NET Core - cannot find a simple soap request code

I need to send an xml like this
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="**************">
<soap:Header/>
<soap:Body>
<web:Open>
<web:username>USERNAME</web:username>
<web:password>PASSWORD</web:password>
</web:Open>
</soap:Body>
</soap:Envelope>
from this tutorial https://stackify.com/soap-net-core/
var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress(new Uri("http://server/PingService.svc"));
var channelFactory = new ChannelFactory(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
var result = serviceClient.Ping("Ping");
channelFactory.Close();
but how do I modify this code to do my own request ?
I parsed microsoft documentation about WCF and svcutils and it appears infuriatingly complicated
I mean, all that, just to send an XML ?
how to I do a SOAP request in the simplest manner possible ?
thanks for helping me on this
The simplest way is to import the wsdl from the server side into your project. this will generate most of the required code. An example has been provided in the other question that you asked related to this.
It is also possible to do it completely manually. First you need create one or 2 xml schema's that describe your header and payload (the header is optional).
Open.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:web="http://bvdep.com/webservices/" targetNamespace="http://bvdep.com/webservices/" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="OpenType">
<xs:sequence>
<xs:element name="username" type="xs:string"/>
<xs:element name="password" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Open" type="web:OpenType"/>
</xs:schema>
header.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:head="http://bvdep.com/webservices/Header" targetNamespace="http://bvdep.com/webservices/Header" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Header" type="head:HeaderType"/>
<xs:complexType name="HeaderType">
<xs:sequence>
<xs:element name="From" type="xs:string"/>
<xs:element name="To" type="xs:string"/>
<xs:element name="MsgType" type="xs:string"/>
<xs:element name="Datetime" type="xs:dateTime"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
then you use xsd.exe to generate class files. I use a bat file to do so.
#echo off
set exepad=C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe
set sourcepad=..\..\
set xsdpad=%sourcepad%\ConsoleCore\xsd
set Outpad=%sourcepad%\ConsoleCore\generated
Set NameSpace=ConsoleCore.generated
"%exepad%" "%xsdpad%\Open.xsd" /c /n:%NameSpace% /o:%Outpad%
"%exepad%" "%xsdpad%\Header.xsd" /c /n:%NameSpace% /o:%Outpad%
In your vs core project you need to add 2 nuget packages
System.ServiceModel.Primitives and System.ServiceModel.Http
next you need to add an interface that describes the service an operation(s) that you want to invoke just as you found in the ping example
[ServiceContract(Namespace = "http://Open.webservice.namespace")]
public interface IOpenService
{
[XmlSerializerFormat()]
[OperationContract(IsOneWay = false, Action = "urn:#OpenOperation")]
OpenReturnMsg OpenOperation(OpenMsg msg);
}
[MessageContract(IsWrapped = false)]
public class OpenMsg
{
[MessageHeader(Name = "Header", Namespace = "http://bvdep.com/webservices/Header")] public HeaderType Header { get; set; }
[MessageBodyMember(Name = "Open", Namespace = "http://bvdep.com/webservices/")] public OpenType Open { get; set; }
}
[MessageContract(IsWrapped = false)]
public class OpenReturnMsg
{
[MessageBodyMember(Name = "ResponseMsg", Namespace = "http://Open.webservice.namespace")] public string ResponseMsg { get; set; }
}
And last the actual statements to invoke the service and get a response:
static void Main(string[] args)
{
Console.WriteLine("Start Program!");
var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress(new Uri("http://LOCALHOST:8085/mockOpenBinding"));
var channelFactory = new ChannelFactory<IOpenService>(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
var msg = new OpenMsg
{
Header = new HeaderType
{
From = "source",
To = "dest",
MsgType = "open",
Datetime = DateTime.Now
},
Open = new OpenType
{
username = "user",
password = "pw"
}
};
var result = serviceClient.OpenOperation(msg);
channelFactory.Close();
Console.WriteLine(result.ResponseMsg);
}
i've tested this using a mock service from the below WSDL in SOAPUI.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://Open.webservice.namespace" xmlns:web="http://bvdep.com/webservices/" xmlns:head="http://bvdep.com/webservices/Header" targetNamespace="http://Open.webservice.namespace">
<wsdl:types>
<xs:schema targetNamespace="http://Open.webservice.namespace" elementFormDefault="qualified">
<xs:import namespace="http://bvdep.com/webservices/Header" schemaLocation="Header.xsd"/>
<xs:import namespace="http://bvdep.com/webservices/" schemaLocation="Open.xsd"/>
<xs:element name="ResponseMsg" type="xs:string"/>
</xs:schema>
</wsdl:types>
<wsdl:message name="OpenMessageHeader">
<wsdl:part name="MsgHeader" element="head:Header"/>
</wsdl:message>
<wsdl:message name="OpenMessageRequest">
<wsdl:part name="Open" element="web:Open"/>
</wsdl:message>
<wsdl:message name="OpenMessageResponse">
<wsdl:part name="Response" element="tns:ResponseMsg"/>
</wsdl:message>
<wsdl:portType name="OpenPortType">
<wsdl:operation name="OpenOperation">
<wsdl:input message="tns:OpenMessageRequest"/>
<wsdl:output message="tns:OpenMessageResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="OpenBinding" type="tns:OpenPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="OpenOperation">
<soap:operation soapAction="urn:#OpenOperation"/>
<wsdl:input>
<soap:body use="literal"/>
<soap:header message="tns:OpenMessageHeader" part="MsgHeader" use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="OpenService">
<wsdl:port name="OpenPort" binding="tns:OpenBinding">
<soap:address location="No Target Adress"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

Error reading entity from input stream on null list

I'm attempting to call a REST endpoint that returns JSON for a validated civic address. On a successful call, I get back something like this:
{
"success":true,
"results":[
{
"civicnumberid":123456,
"civic_address_as_string":"123 Main Street, My City, My Municipality, My County",
"esri_point":{
"x":12345.678,
"y":54321.012
}
}
],
"error":null
}
However if I send a request in a format that the service can't handle, I back back something like this:
{
"success":false,
"results":null,
"error":{
"code":123,
"message":"Invalid Civic Address. Valid Example: 123 Main St, My City...",
"details":[
"The civic address submitted to the service contained an alphabetic character where a number was expected."
]
}
}
Note the "results": null. While attempting to convert the response using JAX-RS 2.0 and Jackson 2.5.1:
ResponseObject response = client.target(url)
.path(REST_REQUEST_CONTEXT)
.queryParam("search_str", searchAddress)
.request(MediaType.APPLICATION_JSON)
.get(ResponseObject.class);
... it fails with "Error reading entity from input stream." Here's my current ObjectMapper setup:
defaultObjectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true)
.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true)
.configure(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS, true)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true)
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
My ResponseObject is a JAXB object:
public class ResponseObject
implements Serializable
{
private final static long serialVersionUID = 1L;
protected Boolean success;
#XmlElement(nillable = true)
protected List<Result> results;
#XmlElement(nillable = true)
protected Error error;
Can "results": null be handled gracefully or should I work with the service provider to return an empty list?
I was wrong in assuming that the null results was the issue. The Error jaxb type was defined using the following schema type:
<xs:complexType name="Error">
<xs:sequence>
<xs:element minOccurs="0" name="code" type="xs:int" />
<xs:element minOccurs="0" name="message" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="details" nillable="true"
type="q1:ArrayOfstring" xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
</xs:sequence>
</xs:complexType>
... which resulted in the following JAXB type:
public class Error {
protected Integer code;
#XmlElement(nillable = true)
protected String message;
#XmlElement(nillable = true)
protected ArrayOfstring details;
But when I changed the schema to this:
<xs:complexType name="Error">
<xs:sequence>
<xs:element minOccurs="0" name="code" type="xs:int" />
<xs:element minOccurs="0" name="message" nillable="true" type="xs:string" />
<!--
<xs:element minOccurs="0" name="details" nillable="true"
type="q1:ArrayOfstring" xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
-->
<xs:element minOccurs="0" name="details" maxOccurs="unbounded" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
... The following JAXB type works:
public class Error {
private final static long serialVersionUID = 1L;
protected Integer code;
#XmlElement(nillable = true)
protected String message;
#XmlElement(nillable = true)
protected List<String> details;

Where to set username and password in a Web Service client?

I was provided this WSDL, and I have to develop a client for it (I've been making questions here about it lol).
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:ManterFornecedor" xmlns:s0="urn:ManterFornecedor" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema elementFormDefault="qualified" targetNamespace="urn:ManterFornecedor">
<xsd:element name="Novo" type="s0:InputMapping1"/>
<xsd:complexType name="InputMapping1">
<xsd:sequence>
<xsd:element name="NO_FORNECEDOR" type="xsd:string"/>
<xsd:element name="DE_CONTRATO" type="xsd:string"/>
<xsd:element name="DH_INICIO" nillable="true" type="xsd:dateTime"/>
<xsd:element name="DH_FIM" nillable="true" type="xsd:dateTime"/>
<xsd:element name="NO_PRODUTO" type="xsd:string"/>
<xsd:element name="IC_STATUS" type="s0:IC_STATUSType" nillable="true"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="IC_STATUSType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Ativo"/>
<xsd:enumeration value="Inativo"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="NovoResponse" type="s0:OutputMapping1"/>
<xsd:complexType name="OutputMapping1">
<xsd:sequence>
<xsd:element name="Id" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="AuthenticationInfo" type="s0:AuthenticationInfo"/>
<xsd:complexType name="AuthenticationInfo">
<xsd:sequence>
<xsd:element name="userName" type="xsd:string"/>
<xsd:element name="password" type="xsd:string"/>
<xsd:element minOccurs="0" name="authentication" type="xsd:string"/>
<xsd:element minOccurs="0" name="locale" type="xsd:string"/>
<xsd:element minOccurs="0" name="timeZone" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="NovoSoapOut">
<wsdl:part element="s0:NovoResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="ARAuthenticate">
<wsdl:part element="s0:AuthenticationInfo" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="NovoSoapIn">
<wsdl:part element="s0:Novo" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="PortPortType">
<wsdl:operation name="Novo">
<wsdl:input message="s0:NovoSoapIn"></wsdl:input>
<wsdl:output message="s0:NovoSoapOut"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="PortSoapBinding" type="s0:PortPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Novo">
<soap:operation soapAction="urn:ManterFornecedor/Novo" style="document"/>
<wsdl:input>
<soap:header message="s0:ARAuthenticate" part="parameters" use="literal"></soap:header>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ManterFornecedorService">
<wsdl:documentation>Fornecedor</wsdl:documentation>
<wsdl:port binding="s0:PortSoapBinding" name="PortSoap">
<soap:address location="http://somewhere&webService=ManterFornecedor"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I provided the full WSDL, but the important part for the question is
<soap:operation soapAction="urn:ManterFornecedor/Novo" style="document"/>
<wsdl:input>
<soap:header message="s0:ARAuthenticate" part="parameters" use="literal"></soap:header>
<soap:body use="literal"/>
</wsdl:input>
As you can see, input has a ARAuthenticate message in its header, which is
<wsdl:message name="ARAuthenticate">
<wsdl:part element="s0:AuthenticationInfo" name="parameters"></wsdl:part>
</wsdl:message>
<xsd:element name="AuthenticationInfo" type="s0:AuthenticationInfo"/>
<xsd:complexType name="AuthenticationInfo">
<xsd:sequence>
<xsd:element name="userName" type="xsd:string"/>
<xsd:element name="password" type="xsd:string"/>
<xsd:element minOccurs="0" name="authentication" type="xsd:string"/>
<xsd:element minOccurs="0" name="locale" type="xsd:string"/>
<xsd:element minOccurs="0" name="timeZone" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
I used Eclipse's Web Services Explorer to create a WS client to test this webservice, and it worked! This client has username and password fields to be set.
Ok, now I need to take this client exemple code, and implement a standalone (not web UI) solution that gathers info and uses the client to send it to the server. But it's failing, and I believe it's because authentication.
Only place I see username and password being set is in PortSoapBindingStub.createCall():
org.apache.axis.client.Call _call = super._createCall();
if (super.maintainSessionSet) {
_call.setMaintainSession(super.maintainSession);
}
if (super.cachedUsername != null) {
_call.setUsername(super.cachedUsername);
}
if (super.cachedPassword != null) {
_call.setPassword(super.cachedPassword);
}
if (super.cachedEndpoint != null) {
_call.setTargetEndpointAddress(super.cachedEndpoint);
}
if (super.cachedTimeout != null) {
_call.setTimeout(super.cachedTimeout);
}
if (super.cachedPortName != null) {
_call.setPortName(super.cachedPortName);
}
But, where are these cached stuff coming from? I tried to edit this code and manually set them, but keep receiving error:
Exception in thread "main" AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.lang.ArrayIndexOutOfBoundsException: -1
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}hostname:myhost
java.lang.ArrayIndexOutOfBoundsException: -1
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:129)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.transport.http.HTTPSender.readFromSocket(HTTPSender.java:796)
at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:144)
at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at ManterFornecedor.PortSoapBindingStub.novo(PortSoapBindingStub.java:174)
at ManterFornecedor.PortPortTypeProxy.novo(PortPortTypeProxy.java:50)
at caixa.pedes.br.ManterFornecedor.main(ManterFornecedor.java:43)
Here's my code:
import java.net.MalformedURLException;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import org.apache.axis.AxisFault;
import org.apache.axis.client.Call;
import ManterFornecedor.*;
public class ManterFornecedor {
public static void main(String[] args) throws RemoteException, ServiceException, MalformedURLException {
InputMapping1 parameters = new InputMapping1(
"fornecedor","contrato",java.util.Calendar.getInstance(), java.util.Calendar.getInstance(),
"produto",IC_STATUSType.Ativo
);
java.net.URL endpoint = new java.net.URL("http://somewhere&webService=ManterFornecedor");
PortPortTypeProxy proxy = new PortPortTypeProxy();
ManterFornecedorServiceLocator locator = new ManterFornecedorServiceLocator();
ManterFornecedor.PortPortType port = locator.getPortSoap();
PortSoapBindingStub client = new PortSoapBindingStub(endpoint,locator);
ManterFornecedor.OutputMapping1 response = proxy.novo(parameters);
System.out.println(response);
}
}
Edit: as you can see, I'm new to Web Service and I'm kinda lost. I don't know exactally why, but the novo() method is available in Proxy, Locator and Stub. I'll read more about these design patterns because I'm new to them too, and using all 3 together is even more troublesome.
What's the best object to use to call WSDL generated operators? Unfortuntely, client code created in Eclipse uses JSP to receive parameters, and I'm not being able to properly isolate exemple code to real client so that I can develop my code and call client's operator.
It would be much easier if client was encapsulated in a unique class where I just had to provide its configs (endpoint, authentication, etc) and then call the operator.
You must put this code before to setRequestHeaders(_call); in the PortTypeSoapBindingStub class
try {
SOAPHeaderElement sopElement = new SOAPHeaderElement("urn:AuthenticationInfo","AuthenticationInfo") ;
sopElement.addChildElement("userName").addTextNode("XXXXX") ;
sopElement.addChildElement("password").addTextNode("XXXX");
sopElement.addChildElement("authentication").addTextNode("");
sopElement.addChildElement("locale").addTextNode("");
sopElement.addChildElement("timeZone").addTextNode("");
_call.addHeader(sopElement);
} catch (Exception e) {
e.printStackTrace();
}
I also struggled to achieve the same, later I found the NTLM Authentication wasn't enabled in the mac machine used at server
The following code worked for me
public static void testNavisionMicrosoft() {
static String baseURL = "file:C://locapath//customer.wsdl";
URL url = null;
try {
url = new URL(baseURL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URL url2 = null;
try {
url2 = new URL("http://localhost:8080/customer?wsdl");
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
final String username = "user";
final String password = "paswd";
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password
.toCharArray());
}
});
QName qname = new QName("search for soapActionin your wsdl file",
"search for service name in wsdl file");
Service service = Service.create(url, qname);
CRMCustomerPort proxy = service.getPort(CRMCustomerPort.class);
Map<String, Object> requestContext = ((BindingProvider) proxy)
.getRequestContext();
requestContext.put(BindingProvider.USERNAME_PROPERTY, username);
requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("Timeout", Collections.singletonList("10000"));
requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
CRMCustomer data = proxy.read("AIL0003190");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(
"Error occurred in operations web service client initialization",
e);
}
}

Tool or a way to create a DataSet.XSD from a Mapping C# .cs file or a NHibernate.hbm.xml file?

I need to create a DataSet.xsd file according to a NHibernate.hbm.xml file or a Class File. These are Mapping files and class files than we use to work with our DB.
You may ask me, why I do need a DataSet file, generating from a Nhibernate.hbm.xml file or a .cs file?
It's because we're using Crystal Reports, and we're using Frameworks, MVVM, INotifyPropertyChanged, NHibernate and after a lot of studying, for our case, would be better if we Convert an object while in executing time of program and use it to generate a report. If this tool exists, it will make easier, 'cause we have over 60, 70 columns per table in our DB. Since we're already with all these components working into our Project, it wouldn't make sense if we start to use sql queries to generate reports.
This tool, or 'the way to' create this DataSet file, need to read those file in these formats:
Nhibernate.hbm.xml file:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="PCT.Domain" namespace="Gerdau.PCT.Kernel.Domain">
<class name="Furnace" table="Furnace" lazy="false">
<id name="Id" column="Id_Furnace" type="Int64">
<generator class="Geraes.GLib.GDomainBasis.CustomTableHiLoGenerator, GLib.GDomainBasis" />
</id>
<property name="Name" column="Name" type="String" length="50" not-null="true"/>
<property name="Code" column="Code" type="Char" not-null="true"/>
<property name="Mill" column="Mill" type="String" length="2" not-null="true"/>
<property name="DischEnabled" column="Disch_Enabled" type="Char" not-null="true"/>
<property name="DischEnabledTemp" column="Disch_Enabled_Temp" type="Char" not-null="true"/>
<property name="ChargeEnabled" column="Charge_Enabled" type="Char" not-null="true"/>
<property name="ChargeEnabledTemp" column="Charge_Enabled_Temp" type="Char" not-null="true"/>
</class>
</hibernate-mapping>
CSharp .cs File:
public class Furnace : BaseEntity
{
public virtual String Name { get; set; }
public virtual Char Code { get; set; }
public virtual String Mill { get; set; }
public virtual Char DischEnabled { get; set; }
public virtual Boolean DischEnabledConv
{
get
{
return DischEnabled.ConvertYesNoToBoolean();
}
set
{
DischEnabled = ((Boolean)value).ConvertYesNoToBoolean();
}
}
public virtual Boolean DischEnabledTempConv
{
get
{
return DischEnabledTemp.ConvertYesNoToBoolean();
}
set
{
DischEnabledTemp = ((Boolean)value).ConvertYesNoToBoolean();
}
}
public virtual Char DischEnabledTemp { get; set; }
public virtual Char ChargeEnabled { get; set; }
public virtual Boolean ChargeEnabledConv
{
get
{
return ChargeEnabled.ConvertYesNoToBoolean();
}
set
{
ChargeEnabled = ((Boolean)value).ConvertYesNoToBoolean();
}
}
public virtual Boolean ChargeEnabledTempConv
{
get
{
return ChargeEnabledTemp.ConvertYesNoToBoolean();
}
set
{
ChargeEnabledTemp = ((Boolean)value).ConvertYesNoToBoolean();
}
}
public virtual Char ChargeEnabledTemp { get; set; }
public virtual ConfiguracaoForno MillConv
{
get
{
if (Mill == ConfiguracaoForno.SM.ToString())
return ConfiguracaoForno.SM;
if (Mill == ConfiguracaoForno.PM.ToString())
return ConfiguracaoForno.PM;
else
return ConfiguracaoForno.NN;
}
}
public override String ToString()
{
return "Forno " + Code + " (" + Name + "): Laminador " + MillConv;
}
}
I know it's an very specific case, but if you can show to us at least a way, it'll be of great help.
Best regards,
Gustavo
Edit:
Found a way to do it: using XSD.EXE, a internal Tool from Visual Studio, i've extracted the mapping from my assembly:
C:\>xsd / c /l:CS -t:Furnace <MyAssembly>.dll -o:"D:\Temp"
But now, when I do this:
D:\>xsd /c schema0.xsd
Results in these errors:
D:\Temp>xsd /c schema0.xsd
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 4.0.30319.1]
Copyright (C) Microsoft Corporation. All rights reserved.
Schema validation warning: Type 'char' is not declared, or is not a simple type.
Line 21, position 5.
Schema validation warning: Type 'http://microsoft.com/wsdl/types/:char' is not declared. Line 10, position 7.
Schema validation warning: Type 'http://microsoft.com/wsdl/types/:char' is not declared. Line 12, position 7.
Schema validation warning: Type 'http://microsoft.com/wsdl/types/:char' is not declared. Line 15, position 7.
Schema validation warning: Type 'http://microsoft.com/wsdl/types/:char' is not declared. Line 16, position 7.
Schema validation warning: Type 'http://microsoft.com/wsdl/types/:char' is not declared. Line 19, position 7.
Warning: Schema could not be validated. Class generation may fail or may produce incorrect results.
Error: Error generating classes for schema 'schema0'.
- The datatype 'char' is missing.
If you would like more help, please type "xsd /?".
Here's my generated schema.xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://microsoft.com/wsdl/types/" />
<xs:element name="Furnace" nillable="true" type="Furnace" />
<xs:complexType name="Furnace">
<xs:complexContent mixed="false">
<xs:extension base="BaseEntity">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="Code" xmlns:q1="http://microsoft.com/wsdl/types/" type="q1:char" />
<xs:element minOccurs="0" maxOccurs="1" name="Mill" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="DischEnabled" xmlns:q2="http://microsoft.com/wsdl/types/" type="q2:char" />
<xs:element minOccurs="1" maxOccurs="1" name="DischEnabledConv" type="xs:boolean" />
<xs:element minOccurs="1" maxOccurs="1" name="DischEnabledTempConv" type="xs:boolean" />
<xs:element minOccurs="1" maxOccurs="1" name="DischEnabledTemp" xmlns:q3="http://microsoft.com/wsdl/types/" type="q3:char" />
<xs:element minOccurs="1" maxOccurs="1" name="ChargeEnabled" xmlns:q4="http://microsoft.com/wsdl/types/" type="q4:char" />
<xs:element minOccurs="1" maxOccurs="1" name="ChargeEnabledConv" type="xs:boolean" />
<xs:element minOccurs="1" maxOccurs="1" name="ChargeEnabledTempConv" type="xs:boolean" />
<xs:element minOccurs="1" maxOccurs="1" name="ChargeEnabledTemp" xmlns:q5="http://microsoft.com/wsdl/types/" type="q5:char" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="BaseEntity">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Id" type="xs:long" />
</xs:sequence>
</xs:complexType>
</xs:schema>
I appreciate for any help.
Gustavo
You're missing an XSD file.
UPDATE: Let's assume you're staying with xsd.exe. In this case, modify the import statement as following (I call this file XSD-1.xsd):
<xs:import namespace="http://microsoft.com/wsdl/types/" schemaLocation="XSD-2.xsd" />
Copy the content below in XSD-2.xsd file, in the same folder:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://microsoft.com/wsdl/types/" elementFormDefault="qualified" targetNamespace="http://microsoft.com/wsdl/types/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="char">
<xs:restriction base="xs:unsignedShort" />
</xs:simpleType>
</xs:schema>
Run the xsd.exe with the following line:
xsd XSD-1.xsd /c
You should get an XSD-1.cs file and some warnings
If you want to use svcutil, you must have the XSD-2.xsd, otherwise it won't work; also, on the plus side you don't have to modify the XSD-1.xsd:
svcutil XSD-1.xsd XSD-2.xsd /dconly
It works fine, without any errors. I am running v4.

generate wcf server code from wsdl files

Greetings, I would like to generate some contract based on wsdl file. I used svcutil but I suspect it generated it wrong as all contract methods have void returned type. Is there any tool for this purpose?
EDIT:
here is the wsdl file:
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:tns="http://dantek.com.pl/EDItEUR/EDItX/LibraryBookSupply/WebService/CustomerService/20100611/ServiceContract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" targetNamespace="http://mytargetNamespace/ServiceContract" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema targetNamespace="http://mytargetNamespace/ServiceContract/Imports">
<xsd:import namespace="http http://mytargetNamespace/ServiceContract/ServiceContract" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="CustomerService_ProcessMethod_InputMessage">
<wsdl:part name="parameters" element="tns:ProcessMethod" />
</wsdl:message>
<wsdl:message name="CustomerService_ProcessMethod_OutputMessage">
<wsdl:part name="parameters" element="tns:ProcessMethodResponse" />
</wsdl:message>
>
<wsdl:portType name="CustomerService">
<wsdl:operation name="ProcessShipNotice">
<wsdl:input wsaw:Action=" http://mytargetNamespace/ServiceContract/ProcessMethod" message="tns:CustomerService_ProcessMethod_InputMessage" />
<wsdl:output wsaw:Action=" http://mytargetNamespace/ServiceContract/ProcessMethod" message="tns:CustomerService_ProcessMethod_OutputMessage" />
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
And the contract created
[ServiceContract]
public interface CustomerService
{
[System.ServiceModel.OperationContractAttribute(Action = "http://mytargetNamespace/ServiceContract/CustomerService/ProcessMethod”, ReplyAction = " http://mytargetNamespace/ServiceContract/CustomerService/ProcessMethodResponse")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
void ProcessMethod(ProcessMethodRequest request);
I don't want to have ProcessMethod returned type void but rather ProcessMethodResponse type. How can I achieve it?
EDIT2: Here's my schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://myTargetNamespece/ServiceContract" elementFormDefault="qualified"
targetNamespace="http://myTargetNamespace/ServiceContract" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ProcessMethod">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="request" type="tns:ProcessMethodRequest" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="ProcessMethodRequest" abstract="true" />
<xs:complexType name="ProcessMethodRequestWithPayload"/>
<xs:element name="ProcessMethodResponse">
<xs:complexType />
</xs:element>
</xs:schema>
Generated operation contract is correct. You WSDL specifies request/response operation (= two-way) with empty response. ProcessMethodResponse element is wrapper element for the response message but it does not contain any subelements = void response.
If you want to return ProcessMethodResponse you have to use message contracts. You can instruct svcutil to use message contracts by /mc or /messageContract switch.