I'm creating a WCF service which I want to consume from a Java app. But the question isn't about .net-java interop.
The key point is one of types related to a service operation is IXmlSerializable. That type return its XSD schema with static method referenced by XmlSchemaProviderAttribute. The problem is when we get wsdl for the service through mex-endpoint (http://..svc?wsdl) that schema isn't returned.
Here're the details.
Some wcf service contract:
[ServiceContract]
public interface IService1
{
[OperationContract]
DomainData GetData();
}
DomainData type is:
[DataContract(Namespace = "http://schemas.biz.org/Samples/customserialization")]
public class DomainData
{
[DataMember(Name = "AuxData")]
Dictionary<String, AuxDomainData> m_auxData = new Dictionary<string, AuxDomainData>();
[DataMember]
public string ObjectId { get; set; }
public IDictionary<string, AuxDomainData> AuxData
{
get { return m_auxData; }
}
}
As you can see DomainData contains a dictionary of AuxDomainData objects, which is:
[XmlSchemaProvider("GetXmlSerializationSchema")]
public class AuxDomainData : IXmlSerializable
{
[DataMember]
public Object AuxData { get; set; }
XmlSchema IXmlSerializable.GetSchema() { return null; }
void IXmlSerializable.ReadXml(XmlReader reader) { }
void IXmlSerializable.WriteXml(XmlWriter writer) { }
public static string Namespace = "http://schemas.biz.org/Samples/customserialization";
public static XmlQualifiedName GetXmlSerializationSchema(XmlSchemaSet schemas)
{
var qname = new XmlQualifiedName("AuxDomainData", Namespace);
string resourceName = "CustomSerialization.aux-domain-data.xsd";
using (Stream stream = typeof(AuxDomainData).Assembly.GetManifestResourceStream(resourceName))
{
var schema = XmlSchema.Read(stream, null);
schemas.Add(schema);
}
return qname;
}
}
Here we're returning XSD schema in GetXmlSerializationSchema method. Schema itself is simple but let me skip it here.
That code is straightforward I guess, it's common scenario for IXmlSerializable types.
Now, we want WSDL. I'm going to use WSDL for creating a Java client with help of Metro But actually JDK 1.6 is enough as it contains WS stack (and wsimport.exe). So java wants wsdl with wsdl:service definition. That's why I can't give it a wsdl from wsdl.exe (because a wsdl produced by wsdl doesn't contain wsdl:service definition, only wsdl:portType). So, I call wsimport.bat http://localhost/Service1.svc?wsdl
But what I get in respose is : [ERROR] undefined simple or complex type 'q1:AuxDomainData' line 1 of http://locahost/CustomSerialization/Service1.svc?xsd=xsd3
That's because a composed wsdl actually doesn't contain such type as AuxDomainData. That's true and we can't blame java/metro/any other stack. If we look at wsdl produced by wcf it contains wsdl:types element with imports of all xsd schemas:
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/" />
<xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd2" namespace="http://schemas.biz.org/Samples/customserialization" />
<xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd3" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
</xsd:schema>
</wsdl:types>
I wont' provide all xsd here but the point is there is no AuxDomainData definition in they. The xsd-schema for AuxDomainData type is in http://localhost/CustomSerialization/Service1.svc?xsd=xsd4 "document". But as you can see the root wsdl doesn't contain a reference to it. That's the problem. The result wsdl/xsd schema set isn't complete.
So, what are my options?