generate wcf server code from wsdl files - wcf

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.

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>

WCF Method with parameter not generating right WSDL

I have a simple service definition:
[ServiceContract]
public interface IInterface12
{
[OperationContract]
void SendInterface12(string appId);
}
which I have implemented in the service as:
public void SendInterface12(string appId)
{
The thing is that the string parameter appId is not showing up. The complete WSDL is here:
<?xml version="1.0" encoding="UTF-8"?>
-<wsdl:definitions xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://tempuri.org/" name="Interface12Service">
-<wsdl:types>
-<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import namespace="http://tempuri.org/" schemaLocation="http://localhost/TestInterface12/Interface12Service.svc?xsd=xsd0"/>
<xsd:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" schemaLocation="http://localhost/TestInterface12/Interface12Service.svc?xsd=xsd1"/>
</xsd:schema>
</wsdl:types>
-<wsdl:message name="IInterface12_SendInterface12_InputMessage">
<wsdl:part name="parameters" element="tns:SendInterface12"/>
</wsdl:message>
-<wsdl:message name="IInterface12_SendInterface12_OutputMessage">
<wsdl:part name="parameters" element="tns:SendInterface12Response"/>
</wsdl:message>
-<wsdl:portType name="IInterface12">
-<wsdl:operation name="SendInterface12">
<wsdl:input message="tns:IInterface12_SendInterface12_InputMessage" wsaw:Action="http://tempuri.org/IInterface12/SendInterface12"/>
<wsdl:output message="tns:IInterface12_SendInterface12_OutputMessage" wsaw:Action="http://tempuri.org/IInterface12/SendInterface12Response"/>
</wsdl:operation>
</wsdl:portType>
-<wsdl:binding name="BasicHttpBinding_IInterface12" type="tns:IInterface12">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
-<wsdl:operation name="SendInterface12">
<soap:operation style="document" soapAction="http://tempuri.org/IInterface12/SendInterface12"/>
-<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
-<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
-<wsdl:service name="Interface12Service">
-<wsdl:port name="BasicHttpBinding_IInterface12" binding="tns:BasicHttpBinding_IInterface12">
<soap:address location="http://localhost/TestInterface12/Interface12Service.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
What am I missing? I have to have a service operation that takes a parameter but when I generate the proxy, there is no parameter for the string appId parameter. It says it takes 0 parameters.
Most probably the WSDL references an XSD file where your parameter is defined. Search for "import" or "include" to see the location of that XSD. If this is your wsdl location: http://myserver.com/X.svc?WSDL=WSDL0 then the XSD is in http://myserver.com/x.svc?XSD=XSD0 (or XSD1, XSD2...). Possibly your WSDL references another WSDL (WSDL1) which is the one that references the XSD (or a few of them).

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

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

SOAP Message contains an extra tag after generation from WSCF Blue in Visual Studio 2008

I'm using Visual Studio 2008 to write a simple web-service but have been running into some problems. You might need to format my
The full expected message is something along the lines of:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace = "http://www.website.com/WS/"
elementFormDefault = "qualified"
xmlns = "http://www.website.com/WS/"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
>
<xs:element name="QUERYFOOTBALL">
<xs:complexType>
<xs:sequence>
<xs:element name="KEY" minOccurs="1" maxOccurs="1" type="xs:string" />
<xs:element name="FOOTBALL">
<xs:complexType>
<xs:sequence>
<xs:element name="HEADER" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="TEAM_ID" minOccurs="1" maxOccurs="1" type="xs:string" />
<xs:element name="MATCH_ID" minOccurs="1" maxOccurs="1" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GAME" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="ONE" minOccurs="1" maxOccurs="1" type="xs:string" />
<xs:element name="TWO" minOccurs="1" maxOccurs="1" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
However when I generate the service the SOAP message layout/call appears like so
<?xml version="1.0" encoding="utf-8"?>
<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>
<QueryFootball xmlns="http://www.website.com/WS/">
<QUERYFOOTBALL>
<KEY>string</KEY>
<FOOTBALL>
<HEADER>
<TEAM_ID>string</TEAM_ID>
<MATCH_ID>string</MATCH_ID>
</HEADER>
<GAME>
<ONE>string</ONE>
<TWO>string</TWO>
</GAME>
</FOOTBALL>
</QUERYFOOTBALL>
</QueryFootball>
</soap:Body>
</soap:Envelope>
My actual C# code looks like this:
namespace FootballSimulator
{
[System.ServiceModel.ServiceBehaviorAttribute(InstanceContextMode=System.ServiceModel.InstanceContextMode.PerCall, ConcurrencyMode=System.ServiceModel.ConcurrencyMode.Single)]
public class FootballSimulator : IFootballSimulator
{
public virtual QUERYFOOTBALLRESPONSE QUERYFOOTBALL(QUERYFOOTBALL request)
{
throw new System.NotImplementedException();
}
}
}
I guess my question is how can I edit the Schema/WSCFBlue so that it doesn't force that extra in the SOAP request?
I would really appreciated any advice/guidance you could give. I can give you an outline to what I did:
In visual studio I right clicked my 2 schemas (request and response message) and selected WSCFblue then Create WSDL Interface Description
I selected the correct schemas/ports and gave them message in a name of QUERYFOOTBALL and the message out a name of QUERYFOOTBALLRESPONSE
I right clicked the WSDL that was generated in above steps and went selected WSCFblue then Generate Data Contract Code (which is does and gives me my objects QUERYFOOTBALL and QUERYFOOTBALLRESPONSE)
I right clicked the WSDL and selected WSCFblue then Generate Web Service Code
If there is anything obvious that I am doing wrong I would really appreciated it if you can show me what it is. It looks asthough the method name is the causing the additional tag to be added around the expected soap message. In my schema after QUERYFOOTBALL element is another element called KEY, this is the reason I cannot just take out QUERYFOOTBALL and create an object called "FOOTBALL".
What I want the web-service to accept is this:
<?xml version="1.0" encoding="utf-8"?>
<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>
<QUERYFOOTBALL>
<KEY>string</KEY>
<FOOTBALL>
<HEADER>
<TEAM_ID>string</TEAM_ID>
<MATCH_ID>string</MATCH_ID>
</HEADER>
<GAME>
<ONE>string</ONE>
<TWO>string</TWO>
</GAME>
</FOOTBALL>
</QUERYFOOTBALL>
</soap:Body>
</soap:Envelope>
Really appreciate any help you can give, look forward to hearing your experiences/opinions/advice
Better late than never....
Try adding this to your Web Method:
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]

svcutil soap fault namespace problem

I'm generating client side web service code using svcutil. The wsdl contract I'm using contains a soap fault. When the code is generated the fault seems to be wrapped in the namespace it was defined in the contract.
Can anyone explain why?
I'm simply running svcutil [filename]
Example WSDL:
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://tempuri.org/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="HelloFault">
<s:complexType/>
</s:element>
<s:element name="HelloWorld">
<s:complexType/>
</s:element>
<s:element name="HelloWorldResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="HelloWorldSoapIn">
<wsdl:part name="parameters" element="tns:HelloWorld"/>
</wsdl:message>
<wsdl:message name="HelloWorldSoapOut">
<wsdl:part name="parameters" element="tns:HelloWorldResponse"/>
</wsdl:message>
<wsdl:message name="NewMessage">
<wsdl:part name="detail" element="tns:HelloFault"/>
</wsdl:message>
<wsdl:portType name="Service1Soap">
<wsdl:operation name="HelloWorld">
<wsdl:input message="tns:HelloWorldSoapIn"/>
<wsdl:output message="tns:HelloWorldSoapOut"/>
<wsdl:fault name="FaultName" message="tns:NewMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Service1Soap12" type="tns:Service1Soap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="HelloWorld">
<soap12:operation soapAction="http://tempuri.org/HelloWorld" soapActionRequired="" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
<wsdl:fault name="FaultName">
<soap12:fault name="FaultName" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
Generates:
namespace tempuri.org
{
using System.Runtime.Serialization;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="HelloFault", Namespace="http://tempuri.org/")]
public partial class HelloFault : object, System.Runtime.Serialization.IExtensibleDataObject
{
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}
}
}
But other types declared in the contract are declared without a namespace?
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class HelloWorldRequest
{
...
You have to use the /UseSerializerForFaults attribute on svcutil, this will cause the XmlSerializer to be used for reading and writing faults (but only those), instead of the default DataContractSerializer (which will still be used for the rest of the stuff).
This seems to be a genuine bug - more info on my blog post.
I'm not sure I understand what the problem is... can you clarify?
From the looks of it, it would seem WCF is doing the right thing... the generated class has the right namespace URI in the [DataContract] attribute according to the schema in the WSDL fragment you showed.
What were you expecting?
Update: OK, I see what you're saying, but in this specific case, it's not unexpected either. If you look closely, notice that the other class you mention (HelloWorldRequest) is a Message Contract, not a DataContract. Message Contracts don't have namespaces themselves, though they can specify a namespace for the wrapper element around the message body (see the WrapperNamespace property).
In your case, the message contract specifies that it is not wrapped, so the WrapperNamespace wouldn't apply anyway.
Update #2: Regarding the CLR namespace (and not the XML namespace URI), SvcUtil does give you a way to control that; check out the /namespace: argument in the documentation.