I'm trying to create a WCF service (.Net 4.5 in VS2012) for file uploads that can be consumed by clients in other languages, Java (using CXF) in particular. I've got the WCF side of things working great from .Net clients, but am having some issues on the CXF side.
When I try to generate the proxy in CXF from the WSDL through Eclipse (4.2/Juno), I'm getting an exception that prevents the proxy from being created:
wsdl2java -client -d C:\Users\Ryan\workspace\WcfProxy\.cxftmp/src -classdir C:\Users\Ryan\workspace\WcfProxy\build\classes -p http://tempuri.org/=org.tempuri -impl -validate -exsh false -dns true -dex true -wsdlLocation http://localhost:10186/UploadFile.svc?wsdl -verbose -defaultValues -fe jaxws -db jaxb -wv 1.1 http://localhost:10186/UploadFile.svc?wsdl
wsdl2java - Apache CXF 2.7.0
WSDLToJava Error: Schema Error : src-resolve: Cannot resolve the name 'ns0:StreamBody' to a(n) 'type definition' component.
org.apache.cxf.tools.common.ToolException: Schema Error : src-resolve: Cannot resolve the name 'ns0:StreamBody' to a(n) 'type definition' component.
at org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.validateSchema(JAXBDataBinding.java:914)
at org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.addSchemas(JAXBDataBinding.java:586)
at org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:392)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.generateTypes(WSDLToJavaContainer.java:603)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:248)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:142)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:300)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:103)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:184)
Caused by: org.xml.sax.SAXParseException; src-resolve: Cannot resolve the name 'ns0:StreamBody' to a(n) 'type definition' component.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseNamedElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseLocal(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseLocalElements(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(Unknown Source)
at javax.xml.validation.SchemaFactory.newSchema(Unknown Source)
at org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.validateSchema(JAXBDataBinding.java:909)
... 10 more
My WCF service contract is as follows:
<ServiceContract()>
Public Interface IUploadFile
<OperationContract()>
Sub UploadFile(ByVal remoteFile As RemoteFile)
<OperationContract()>
Function DownloadFile() As RemoteFile
End Interface
My WCF message contract (RemoteFile) is as follows:
<MessageContract()> _
Public Class RemoteFile
Implements IDisposable
<MessageHeader(MustUnderstand:=True)> _
Public FileName As String
<MessageHeader(MustUnderstand:=True)> _
Public Length As Long
<MessageBodyMember(Order:=1)> _
Public FileByteStream As System.IO.Stream
Public Sub Dispose() Implements IDisposable.Dispose
If FileByteStream IsNot Nothing Then
FileByteStream.Close()
FileByteStream = Nothing
End If
End Sub
End Class
My WCF service configuration is as follows:
...
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="FileTransferServicesBinding"
transferMode="Streamed"
messageEncoding="Mtom"
maxReceivedMessageSize="10067108864">
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="UploadServiceBehavior" name="Server.UploadFile">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="FileTransferServicesBinding"
contract="Server.IUploadFile" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="UploadServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
...
My WSDL is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="UploadFile" targetNamespace="http://tempuri.org/">
<wsp:Policy wsu:Id="BasicHttpBinding_IUploadFile_policy">
<wsp:ExactlyOne>
<wsp:All>
<wsoma:OptimizedMimeSerialization/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost:10186/UploadFile.svc?xsd=xsd1" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://localhost:10186/UploadFile.svc?xsd=xsd0" namespace="http://schemas.microsoft.com/Message"/>
<xsd:import schemaLocation="http://localhost:10186/UploadFile.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="RemoteFile">
<wsdl:part name="parameters" element="tns:RemoteFile"/>
</wsdl:message>
<wsdl:message name="RemoteFile_Headers">
<wsdl:part name="FileName" element="tns:FileName"/>
<wsdl:part name="Length" element="tns:Length"/>
</wsdl:message>
<wsdl:message name="IUploadFile_DownloadFile_InputMessage"/>
<wsdl:portType name="IUploadFile">
<wsdl:operation name="UploadFile">
<wsdl:input wsaw:Action="http://tempuri.org/IUploadFile/UploadFile" name="RemoteFile" message="tns:RemoteFile"/>
</wsdl:operation>
<wsdl:operation name="DownloadFile">
<wsdl:input wsaw:Action="http://tempuri.org/IUploadFile/DownloadFile" message="tns:IUploadFile_DownloadFile_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IUploadFile/DownloadFileResponse" name="RemoteFile" message="tns:RemoteFile"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_IUploadFile" type="tns:IUploadFile">
<wsp:PolicyReference URI="#BasicHttpBinding_IUploadFile_policy"/>
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="UploadFile">
<soap:operation soapAction="http://tempuri.org/IUploadFile/UploadFile" style="document"/>
<wsdl:input name="RemoteFile">
<soap:header message="tns:RemoteFile_Headers" part="FileName" use="literal"/>
<soap:header message="tns:RemoteFile_Headers" part="Length" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
</wsdl:operation>
<wsdl:operation name="DownloadFile">
<soap:operation soapAction="http://tempuri.org/IUploadFile/DownloadFile" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="RemoteFile">
<soap:header message="tns:RemoteFile_Headers" part="FileName" use="literal"/>
<soap:header message="tns:RemoteFile_Headers" part="Length" use="literal"/>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="UploadFile">
<wsdl:port name="BasicHttpBinding_IUploadFile" binding="tns:BasicHttpBinding_IUploadFile">
<soap:address location="http://localhost:10186/UploadFile.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Obviously the exception indicates it is having an issue creating the stream body type of the message, but does anyone see what I'm doing wrong or need to change to be able to generate a CXF proxy for this WCF service?
EDIT Added WSDL to original post.
Related
I don't want to set the namespace for every single one of my data contracts so I decided to use the ContractNamespace attribute in the AssemblyInfo.cs file of the project where my DataContracts reside. Here is the entry
[assembly: ContractNamespace("http://www.mycompany.com/MyProject/", ClrNamespace = "Company.Project.Client.Entities")]
This does nothing. It seems I HAVE to specify the namespace on all the data contracts like so:
[DataContract(Namespace = "http://www.mycompany.com/MyProject/")]
..and yes, I have verified that my DataContracts are in fact in the specified ClrNamespace. Why doesn't this work? I'm using .net 4.5. Thanks.
Update: Here is the WSDL generated when I use explicit namespacing on the contract:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:i0="http://www.company.com/Project/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="AccountService" targetNamespace="http://tempuri.org/">
<wsdl:import namespace="http://www.company.com/Project/" location="http://my.server.local/Project/Account/AccountService.svc?wsdl=wsdl0"/>
<wsdl:types/>
<wsdl:binding name="BasicHttpBinding_IAccountService" type="i0:IAccountService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetByAccountNumber">
<soap:operation soapAction="http://www.company.com/Project/IAccountService/GetByAccountNumber" 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="AccountService">
<wsdl:port name="BasicHttpBinding_IAccountService" binding="tns:BasicHttpBinding_IAccountService">
<soap:address location="http://my.server.local/Project/Account/AccountService.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
And here is the WSDL I see when trying to use the ContractNamespace attribute in the AssemblyInfo.cs
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="AccountService" targetNamespace="http://tempuri.org/">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://my.server.local/Project/Account/AccountService.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://my.server.local/Project/Account/AccountService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="http://my.server.local/Project/Account/AccountService.svc?xsd=xsd2" namespace="http://www.company.com/Project/"/>
<xsd:import schemaLocation="http://my.server.local/Project/Account/AccountService.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/Company.Project.Core"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IAccountService_GetByAccountNumber_InputMessage">
<wsdl:part name="parameters" element="tns:GetByAccountNumber"/>
</wsdl:message>
<wsdl:message name="IAccountService_GetByAccountNumber_OutputMessage">
<wsdl:part name="parameters" element="tns:GetByAccountNumberResponse"/>
</wsdl:message>
<wsdl:portType name="IAccountService">
<wsdl:operation name="GetByAccountNumber">
<wsdl:input wsaw:Action="http://tempuri.org/IAccountService/GetByAccountNumber" message="tns:IAccountService_GetByAccountNumber_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IAccountService/GetByAccountNumberResponse" message="tns:IAccountService_GetByAccountNumber_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_IAccountService" type="tns:IAccountService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetByAccountNumber">
<soap:operation soapAction="http://tempuri.org/IAccountService/GetByAccountNumber" 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="AccountService">
<wsdl:port name="BasicHttpBinding_IAccountService" binding="tns:BasicHttpBinding_IAccountService">
<soap:address location="http://my.server.local/Project/Account/AccountService.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Ok, I had two issues here. First was a typo in one of the ClrNamespace that I can't believe took me so long to notice. The second was that my Contracts were in a project, lets say Company.Project.Contracts. That project had a few folders, lets say Data and Service (for data and service contracts), and had some contracts in the namespace Company.Project.Contracts. Thus, in my AssemblyInfo.cs file, I had to have MULTIPLE ContractNamespace attributes like so:
[assembly: ContractNamespace("http://www.company.com/Project/", ClrNamespace = "Company.Project.Business.Contracts")]
[assembly: ContractNamespace("http://www.company.com/Project/", ClrNamespace = "Company.Project.Business.Contracts.Service")]
[assembly: ContractNamespace("http://www.company.com/Project/", ClrNamespace = "Company.Project.Business.Contracts.Data")]
Also, #nodots, thanks for the pointers/help.
The ContractNamespace only applies to data contracts. You still have to set the service namespace on [ServiceContract].
The line
<xsd:import schemaLocation="http://my.server.local/Project/Account/AccountService.svc?xsd=xsd2" namespace="http://www.company.com/Project/"/>
in your WSDL indicates the ContractNamespace attribute does work.
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).
Microsoft MSDN describes the most universal service contract for a request reply operation as
[ServiceContract]
public interface IUniversalRequestReply
{
[OperationContract(Action="*", ReplyAction="*")]
Message ProcessMessage(Message msg);
}
If I make a contract like the one below, using basicHttp binding, it will not be WS-I compliant (using SOAPUI compliance check).
[OperationContract]
Message SomeOperation(Message msg);
I would think the most universal contract also would be the most interoperable.
Can anyone explain why it is not WS-I compliant? And more importantly - will using the Message class make the service less consumable to Java clients?
Any experience using the Message class is appreciated.
EDIT After first answer:
This is the full WSDL showing the service contract and operation contract.
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:tns="http://tempuri.org/" 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:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract"
xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="UniversalRequestReply" targetNamespace="http://tempuri.org/">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost:52437/UniversalRequestReply.svc?xsd=xsd0" namespace="http://schemas.microsoft.com/Message"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IUniversalRequestReply_SomeOperation_InputMessage">
<wsdl:part xmlns:q1="http://schemas.microsoft.com/Message" name="msg" type="q1:MessageBody"/>
</wsdl:message>
<wsdl:message name="IUniversalRequestReply_SomeOperation_OutputMessage">
<wsdl:part xmlns:q2="http://schemas.microsoft.com/Message" name="SomeOperationResult" type="q2:MessageBody"/>
</wsdl:message>
<wsdl:portType name="IUniversalRequestReply">
<wsdl:operation name="SomeOperation">
<wsdl:input wsaw:Action="http://tempuri.org/IUniversalRequestReply/SomeOperation" message="tns:IUniversalRequestReply_SomeOperation_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IUniversalRequestReply/SomeOperationResponse" message="tns:IUniversalRequestReply_SomeOperation_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_IUniversalRequestReply" type="tns:IUniversalRequestReply">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="SomeOperation">
<soap:operation soapAction="http://tempuri.org/IUniversalRequestReply/SomeOperation" 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="UniversalRequestReply">
<wsdl:port name="BasicHttpBinding_IUniversalRequestReply" binding="tns:BasicHttpBinding_IUniversalRequestReply">
<soap:address location="http://localhost:52437/UniversalRequestReply.svc/basic"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
What the WSI Compliance test fails is not a missing service contract, but the Message input itself:
Name of message that failed: {http://tempuri.org/}IUniversalRequestReply_SomeOperation_InputMessage
Message: name={http://tempuri.org/}IUniversalRequestReply_SomeOperation_InputMessage
Part: name=msg
typeName={http://schemas.microsoft.com/Message}MessageBody
So using this Message class is not WS-I compliant of some reason.
The reason is the service is not complaint is because it does not define any service contract. Universal means this service can consume the soap message generated by any client that calls it. It does not attempt to deserialize the soap message because it never defines a contract of its own. WS-I compliance requires that a service define a static contract that can be expressed in WSDL.
I have been trying to generate a Proxy class in VB.NET using a WSDL file for an Apache Axis SOAP Web Service.
They have provided me the WSDL file and when I use the WSDL.exe command (In Visual Studio 08) and point it to the local path I get an error.
wsdl /language:vb c:\Orders.wsdl
(I am trying to create a .NET Client that consumes the SOAP Web Service Hosted on Apache Axis 2)
The Error
Unable to import binding 'OrdersSoapBinding' from namespace 'urn:company:orders:schemas:OrderTypes:1.00'.
-Unable to import operation 'placeOrder'
-The element 'urn:company:remtp:schemas:PlaceOrderRequest:1.00:PlaceOrderRequest' is missing
if you would like more help, please type 'wsdl /?'
If I use the svcutil.exe I also get an error message...
svcutil.exe C:\Orders.wsdl /t:code /l:VB /o:"C:\Orders.VB"
What is causing the problem?
Your help will be much appreciated, Thank you.
WSDL Code
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
targetNamespace="urn:company:orders:schemas:OrderTypes:1.00"
xmlns:impl="urn:company:orders:schemas:OrderTypes:1.00"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:poreq="urn:company:remtp:schemas:PlaceOrderRequest:1.00"
xmlns:poresp="urn:company:remtp:schemas:PlaceOrderResponse:1.00"
xmlns:coreq="urn:company:remtp:schemas:CommitOrderRequest:1.00"
xmlns:coresp="urn:company:remtp:schemas:CommitOrderResponse:1.00"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:company:orders:schemas:OrderTypes:1.00">
<import namespace="urn:company:remtp:schemas:PlaceOrderRequest:1.00" schemaLocation="../schemas/placeOrderRequest.xsd"/>
<import namespace="urn:company:remtp:schemas:PlaceOrderResponse:1.00" schemaLocation="../schemas/placeOrderResponse.xsd"/>
<import namespace="urn:company:remtp:schemas:CommitOrderRequest:1.00" schemaLocation="../schemas/commitOrderRequest.xsd"/>
<import namespace="urn:company:remtp:schemas:CommitOrderResponse:1.00" schemaLocation="../schemas/commitOrderResponse.xsd"/>
</schema>
</wsdl:types>
<wsdl:message name="placeOrderRequest">
<wsdl:part element="poreq:PlaceOrderRequest" name="parameters"/>
</wsdl:message>
<wsdl:message name="placeOrderResponse">
<wsdl:part element="poresp:PlaceOrderResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="commitOrderRequest">
<wsdl:part element="coreq:CommitOrderRequest" name="parameters"/>
</wsdl:message>
<wsdl:message name="commitOrderResponse">
<wsdl:part element="coresp:CommitOrderResponse" name="parameters"/>
</wsdl:message>
<wsdl:portType name="Orders">
<wsdl:operation name="placeOrder">
<wsdl:input message="impl:placeOrderRequest"/>
<wsdl:output message="impl:placeOrderResponse"/>
</wsdl:operation>
<wsdl:operation name="commitOrder">
<wsdl:input message="impl:commitOrderRequest"/>
<wsdl:output message="impl:commitOrderResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="OrdersSoapBinding" type="impl:Orders">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="placeOrder">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="placeOrderRequest">
<wsdlsoap:body use="literal" />
</wsdl:input>
<wsdl:output name="placeOrderResponse">
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="commitOrder">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="commitOrderRequest">
<wsdlsoap:body use="literal" />
</wsdl:input>
<wsdl:output name="commitOrderResponse">
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="OrdersService">
<wsdl:port name="Orders" binding="impl:OrdersSoapBinding">
<wsdlsoap:address location="https://companyorders.co.uk/endpoints/services/Orders"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Looking into the wsdl file you provided, You'll see references to four xsd (xml xchema document) files: they contain the type definitions and validation rules needed by svcutil to create the proxy.
<import namespace="urn:company:remtp:schemas:PlaceOrderRequest:1.00" schemaLocation="../schemas/placeOrderRequest.xsd"/>
<import namespace="urn:company:remtp:schemas:PlaceOrderResponse:1.00" schemaLocation="../schemas/placeOrderResponse.xsd"/>
<import namespace="urn:company:remtp:schemas:CommitOrderRequest:1.00" schemaLocation="../schemas/commitOrderRequest.xsd"/>
<import namespace="urn:company:remtp:schemas:CommitOrderResponse:1.00" schemaLocation="../schemas/commitOrderResponse.xsd"/>
So, You need those xsd files too
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.