2009-12-08 34 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

相關問題