我正在創建一個我想從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