0

我正在创建一个我想从 Java 应用程序使用的 WCF 服务。但问题不在于 .net-java 互操作。

关键点是与服务操作相关的类型之一是 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 架构。Schema 本身很简单,但让我在这里跳过它。

我猜该代码很简单,这是 IXmlSerializable 类型的常见场景。

现在,我们需要 WSDL。我将使用 WSDL 在Metro的帮助下创建 Java 客户端 但实际上 JDK 1.6 就足够了,因为它包含 WS 堆栈(和 wsimport.exe)。所以 java 想要带有 wsdl:service 定义的 wsdl。这就是为什么我不能从 wsdl.exe 给它一个 wsdl(因为 wsdl 生成的 wsdl 不包含 wsdl:service 定义,只有 wsdl:portType)。所以,我调用 wsimport.bat http://localhost/Service1.svc?wsdl

但我得到的是:[ERROR] undefined simple or complex type 'q1:AuxDomainData' line 1 of http://locahost/CustomSerialization/Service1.svc?xsd=xsd3

那是因为组合的 wsdl 实际上不包含 AuxDomainData 之类的类型。这是真的,我们不能责怪 java/metro/任何其他堆栈。如果我们查看由 wcf 生成的 wsdl,它包含 wsdl:types 元素以及所有 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 4 "document" 中。但正如您所见,根 wsdl 不包含对它的引用。那就是问题所在。结果 wsdl/xsd 模式集不完整。

那么,我有哪些选择?

4

2 回答 2

0

您确定 WSDL 没有引用它吗?通常,WCF 将在 <wsdl:message> 元素列表之前包含一个元素,有点像这样:

<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 可能无法识别它。

如果这是问题所在,那么有办法将 WSDL 扁平化。你可以试试。

顺便说一句,mex 端点通常是Service1.svc/mex。WSDL 略有不同。

于 2009-12-08T18:39:34.287 回答
0

实际上,来自“ http://blogs.msdn.com/dotnetinterop/archive/2008/09/23/flatten-your-wsdl-with-this-custom-servicehost-for-wcf.aspx ”的 Aaron 解决方案提出不完全正确。不是想法本身,而是代码。在将该 ExportExtension 用于要求 wsdl 进行下一步的服务之后,服务因类型重复而失败。

我还在 msdn 论坛上问过:http: //social.msdn.microsoft.com/Forums/en-US/wcf/thread/0ea27bec-08cc-4a20-86ce-6e3477abb1c5

于 2009-12-11T16:32:25.370 回答