2009-12-08 130 views
0

我正在创建一个我想从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模式集的结果不完整。

那么,我有什么选择?

回答

0

确定WSDL没有引用它吗?通常情况下,WCF将包括一个元素只是< WSDL的列表:消息之前>元素,有点像这样:

<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.datacontract.org/2004/07/MyServiceNamespace"/> 
     <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/MyServiceNamespace.AnotherNamespace"/> 
     <xsd:import schemaLocation="http://localhost/CustomSerialization/Service1.svc?xsd=xsd4" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> 
    </xsd:schema> 
</wsdl:types> 

检查这一点。它应该在那里。但是,Java可能并不认可它。

如果这是问题,那么有办法flatten the WSDL。你可以试试。

顺便说一下,mex端点一般是Service1.svc/mex。 WSDL略有不同。

+0

我提到了wsdl中的类型部分。 拼合wsdl是一个有趣的想法,谢谢。 – Shrike 2009-12-08 18:51:29

+0

我可以发誓,该部分不在原来的职位。无论如何,如果进口存在,那么问题是Java不处理进口。您必须将其扁平化或将服务切换为使用XmlSerializer(而不是DataContractSerializer)。 – Aaronaught 2009-12-08 19:06:37

+0

的确,我编了几次帖子,你很快:)。抱歉。 所以,扁平化确实有帮助。谢谢。 – Shrike 2009-12-08 19:14:38