我正在创建一个我希望从Java应用程序中使用的WCF服务。但问题不在于.net-java interop。
关键点是与服务操作相关的类型之一是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。我将在Metro的帮助下使用WSDL创建Java客户端 但实际上JDK 1.6就足够了,因为它包含WS堆栈(和wsimport.exe)。 所以java希望wsdl使用wsdl:service definition。这就是为什么我不能从wsdl.exe给它一个wsdl(因为wsdl生成的wsdl不包含wsdl:service定义,只包含wsdl:portType)。 所以,我打电话给wsimport.bat http://localhost/Service1.svc?wsdl
但我得到的是: [错误]未定义简单或复杂类型'q1:AuxDomainData' http://locahost/CustomSerialization/Service1.svc?xsd=xsd3
的第1行那是因为组合的wsdl实际上不包含AuxDomainData这样的类型。这是真的,我们不能责怪java / metro /任何其他堆栈。 如果我们看一下wcf生成的wsdl,它包含带有所有xsd模式导入的wsdl:types元素:
<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-schema位于http://localhost/CustomSerialization/Service1.svc?xsd=xsd 4 “document”中。 但正如您所看到的,根wsdl不包含对它的引用。 那就是问题所在。结果wsdl / xsd架构设置不完整。
那么,我的选择是什么?
答案 0 :(得分:0)
您确定WSDL没有引用它吗?通常,WCF将在&lt; wsdl:message&gt;列表之前包含一个元素。元素,有点像这样:
<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略有不同。
答案 1 :(得分:0)
实际上,Aaron提出的“http://blogs.msdn.com/dotnetinterop/archive/2008/09/23/flatten-your-wsdl-with-this-custom-servicehost-for-wcf.aspx”解决方案变得不完全正确。 不是自己想法,而是代码。将ExportExtension用于多个服务后,请求wsdl进行下一步服务失败,原因是类型出版。
我也在msdn论坛上问过:http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/0ea27bec-08cc-4a20-86ce-6e3477abb1c5。