我正在创建一个我想从Java应用程序使用的WCF服务。但问题不在于.net-java interop。使用IXmlSerializable导出数据合同类型的WSDL/XSD模式
关键点是与服务操作相关的类型之一是IXmlSerializable。该类型使用XmlSchemaProviderAttribute引用的静态方法返回其XSD模式。 问题是当我们通过mex-endpoint(http://..svc?wsdl)获得wsdl的服务时,没有返回模式。
这里的细节。
一些WCF服务合同:
[ServiceContract]
public interface IService1
{
[OperationContract]
DomainData GetData();
}
DomainData类型:
[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; }
}
}
正如你可以看到DomainData包含AuxDomainData对象的字典,它是:
[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;
}
}
这里我们在GetXmlSerializationSchema方法中返回XSD模式。 架构本身很简单,但让我在这里跳过它。
这段代码很简单,我猜想,它是IXmlSerializable类型的常见场景。
现在,我们需要WSDL。我将使用WSDL在Metro 的帮助下创建一个Java客户端。但实际上,JDK 1.6已经足够,因为它包含WS堆栈(和wsimport.exe)。 所以java想要wsdl和wsdl:服务定义。这就是为什么我无法从wsdl.exe中为它提供wsdl的原因(因为wsdl生成的wsdl不包含wsdl:服务定义,只有wsdl:portType)。 所以,我呼吁wsimport.bat http://localhost/Service1.svc?wsdl
但我得到respose是: [错误]未定义简单或复杂类型 'Q1:AuxDomainData' 的http://locahost/CustomSerialization/Service1.svc?xsd=xsd3
1号线这是因为,由WSDL实际不包含AuxDomainData类型。这是真的,我们不能责怪java/metro /任何其他堆栈。 如果我们看一下通过WCF产生WSDL它包含的wsdl:所有XSD架构的进口类型元素:
<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>
我不会”在这里提供的所有XSD但问题是有在他们没有 AuxDomainData定义。 AuxDomainData类型的xsd模式位于http://localhost/CustomSerialization/Service1.svc?xsd=xsd “文档”中。 但是,您可以看到根wsdl不包含对其的引用。 这就是问题所在。 wsdl/xsd模式集的结果不完整。
那么,我有什么选择?
我提到了wsdl中的类型部分。 拼合wsdl是一个有趣的想法,谢谢。 – Shrike 2009-12-08 18:51:29
我可以发誓,该部分不在原来的职位。无论如何,如果进口存在,那么问题是Java不处理进口。您必须将其扁平化或将服务切换为使用XmlSerializer(而不是DataContractSerializer)。 – Aaronaught 2009-12-08 19:06:37
的确,我编了几次帖子,你很快:)。抱歉。 所以,扁平化确实有帮助。谢谢。 – Shrike 2009-12-08 19:14:38