Hi,
I'm currently in the process of creating a WCF webservice which should be compatible with WS-I Basic Profile 1.1. I'm using a wsdl-first approach (actually for the first time), defining first the xsd for the complex types, the WSDL and then using svcutil.exe for generating the according server as well as client-side interfaces/proxies. So far everything works fine. Then I decided to add a fault to my WSDL.
Regenerating with svcutil succeeded, but then I noticed that my generated fault doesn't have the properties I defined in my xsd file (which is imported by my WSDL).
complex data type xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://myprod.services.mycompany.com/groups_v1.xsd"
targetNamespace="http://myprod.services.mycompany.com/groupsfault_v1.xsd">
<xsd:complexType name="groupsFault">
<xsd:sequence>
<xsd:element name="code" type="xsd:int"/>
<xsd:element name="message" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Fault XSD definition
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://myprod.services.mycompany.com/groups_v1.xsd"
targetNamespace="http://myprod.services.mycompany.com/groups_v1.xsd">
<xsd:complexType name="group">
<xsd:sequence>
<xsd:element name="groupDescD" type="xsd:string" />
<xsd:element name="groupDescI" type="xsd:string" />
<xsd:element name="groupProtNr" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
WSDL using both of the above XSDs
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions name="Groups_v1.wsdl"
targetNamespace="http://myprod.services.mycompany.com/groups_v1.wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://myprod.services.mycompany.com/groups_v1.wsdl"
xmlns:fault="http://myprod.services.mycompany.com/groupsfault_v1.xsd"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xsd:schema targetNamespace="http://myprod.services.mycompany.com/groups_v1.wsdl"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:groups="http://myprod.services.mycompany.com/groups_v1.xsd">
<import namespace="http://myprod.services.mycompany.com/groups_v1.xsd" schemaLocation="./Groups.xsd"/>
<import namespace="http://myprod.services.mycompany.com/groupsfault_v1.xsd" schemaLocation="./GroupsFault.xsd"/>
<xsd:element name="getGroupList">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="StationProtNr" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="getGroupListResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="group" type="groups:group" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="groupsFault">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="groupsFault" type="fault:groupsFault"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="getGroupList">
<wsdl:part element="tns:getGroupList" name="parameters" />
</wsdl:message>
<wsdl:message name="getGroupListResponse">
<wsdl:part element="tns:getGroupListResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="groupsFault">
<wsdl:part name="parameters" element="tns:groupsFault" />
</wsdl:message>
<wsdl:portType name="Groups_v1">
<wsdl:operation name="getGroupList">
<wsdl:input name="getGroupList" message="tns:getGroupList"/>
<wsdl:output name="getGroupListResponse" message="tns:getGroupListResponse"/>
<wsdl:fault name="getGroupListFault" message="tns:groupsFault" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Groups_v1_SOAPBinding" type="tns:Groups_v1">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getGroupList">
<soap:operation soapAction="http://myprod.services.mycompany.com/groups_v1/getGroupList" />
<wsdl:input name="getGroupList">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="getGroupListResponse">
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="getGroupListFault">
<soap:fault name="getGroupListFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="getGroupList">
<wsdl:port binding="tns:Groups_v1_SOAPBinding" name="GroupsSOAP">
<soap:address location="http://myprod.services.mycompany.com/groups_v1" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Generated .Net fault object
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Xml.Serialization.XmlSchemaProviderAttribute("ExportSchema")]
[System.Xml.Serialization.XmlRootAttribute(IsNullable=false)]
public partial class groupFault : object, System.Xml.Serialization.IXmlSerializable
{
private System.Xml.XmlNode[] nodesField;
private static System.Xml.XmlQualifiedName typeName = new System.Xml.XmlQualifiedName("groupFault", "http://sicp.services.siag.it/groups_v1.wsdl");
public System.Xml.XmlNode[] Nodes
{
get
{
return this.nodesField;
}
set
{
this.nodesField = value;
}
}
public void ReadXml(System.Xml.XmlReader reader)
{
this.nodesField = System.Runtime.Serialization.XmlSerializableServices.ReadNodes(reader);
}
public void WriteXml(System.Xml.XmlWriter writer)
{
System.Runtime.Serialization.XmlSerializableServices.WriteNodes(writer, this.Nodes);
}
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public static System.Xml.XmlQualifiedName ExportSchema(System.Xml.Schema.XmlSchemaSet schemas)
{
System.Runtime.Serialization.XmlSerializableServices.AddDefaultSchema(schemas, typeName);
return typeName;
}
}
Is this ok?? I'd expect to have an object created that contains properties for "code" and "message" s.t. you can then throw it by using something like
...
throw new FaultException<groupFault>(new groupFault { code=100, message="error" });
...
(sorry for the lower-case type definitions, but this is generated code from the WSDL)
Why doesn't the svcutil.exe generate those properties??
Some sources on the web suggested to add the /useSerializerForFaults option of svcutil. I tried it, it doesn't work giving me an exception that the fault type is missing on the wsdl:portType
declaration. Validation with several other tools succeeded however.
My command line output (maybe that helps for someone to identify any problems):
C:\>svcutil /out:IGroupsServi
ce.cs /n:*,MyCompany.MyProduct.MyModule /UseSerializerForFaults *.wsdl *.xsd
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.2152]
Copyright (c) Microsoft Corporation. All rights reserved.
Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.Se
rviceModel.Description.XmlSerializerMessageContractImporter
Error: The datatype 'http://myprod.services.mycompany.com/groups_v1.wsdl:groupsFault' is
missing.
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:portType[@name='Groups_v1']
Error: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is de
pendent on.
XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:portType[@name='Groups_v1']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:binding[@name='Groups_v1_SOAPBinding']
Error: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is depend
ent on.
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:binding[@name='Groups_v1_SOAPBinding']
XPath to Error Source: //wsdl:definitions[@targetNamespace='http://myprod.services.mycompany.com/groups_v1.wsdl']/wsdl:service[@name='getGroupList']/wsdl:port[@name='Gr
oupsSOAP']
Generating files...
Warning: No code was generated.
If you were trying to generate a client, this could be because the metadata docu
ments did not contain any valid contracts or services
or because all contracts/services were discovered to exist in /reference assembl
ies. Verify that you passed all the metadata documents to the tool.
Warning: If you would like to generate data contracts from schemas make sure to
use the /dataContractOnly option.
C:\>
Any help is VERY appreciated :) thx