从java客户端到WCF Web服务的对象,反序列化错误

时间:2009-07-13 11:26:10

标签: java wcf web-services serialization

从另一个.NET应用程序调用时,我的.NET WCF Web服务运行良好。现在我试图构建一个Java客户端来测试服务,但其中一个方法不起作用。

我尝试发送更新列表。复杂类型是:

<xs:complexType name="ArrayOfRegisterUpdate">
    <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" name="OneUpdateRegister"
                    nillable="true" type="tns:OneUpdateRegister" /> 
    </xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfRegisterUpdate" nillable="true" 
    type="tns:ArrayOfRegisterUpdate" /> 
<xs:complexType name="OneUpdateRegister">
    <xs:sequence>
        <xs:element minOccurs="0" name="Field" type="tns:RegisterField" /> 
        <xs:element minOccurs="0" name="Value" nillable="true" type="xs:anyType" /> 
    </xs:sequence>
</xs:complexType>
<xs:element name="OneUpdateRegister" nillable="true" type="tns:OneUpdateRegister" />

我的Java代理允许我按预期在“值”中插入任何对象(可能是字符串,整数或日期时间)。但是如果我输入一个String,则会启动以下异常:

The formatter threw an exception while trying to deserialize the message: 
There was an error while trying to deserialize parameter http://tempuri.org/:updates. 
The InnerException message was 'There was an error deserializing the object of type 
System.Collections.Generic.List`1
[[xxx.xxx.OneUpdateRegister, XXx.XXx, Version=1.0.0.0, Culture=neutral, `PublicKeyToken=null]]. 
The value 'John' cannot be parsed as the type 'Guid.'. Please see InnerException for more details.

甚至不会调用Web方法。我不知道'Guid'类型与所有这些有什么关系,我只能在简单类型的xsd中看到这种类型。

有什么想法吗?请告诉我任何其他可能有用的信息。谢谢。

4 个答案:

答案 0 :(得分:1)

这个XML Schema片段来自哪里?

您可以发布被调用操作的签名,包括[OperationContract]吗?与服务合同相同。

您正在调用的Java代理的签名是什么?

我担心这个架构可以验证您可能不想要的某些XML。例如,你是否注意到你可以有一个Field,Value,Value序列?

但这并不能解释'Guid'的来源。

答案 1 :(得分:0)

如果我尝试使用null或使用DateTime(Java中的日历),则没有问题。只有字符串似乎有问题。 另一方面,int应该作为字符串发送,因此它们会出现同样的问题。

答案 2 :(得分:0)

我担心我不是真正的专家.Nt ws。我想这就是你问我的服务器端:

[System.ServiceModel.ServiceContractAttribute(Namespace="http://xx.es/ServiceName/", ConfigurationName="ServiceName.InterfaceName")]
public interface InterfaceName{

    ....

    [System.ServiceModel.OperationContractAttribute(Action="http://xx.es/ServiceName/InterfaceName/UpdateRegister", ReplyAction="http://xx.es/ServiceName/InterfaceName/UpdateRegisterRes" +
        "ponse")]
    package.UpdateRegisterReturn UpdateRegister(string user, string password, int id1, int id2, System.Collections.Generic.List<package.OneUpdateRegister> updates);

        ....
  }

我的第一个条目中的XML模式来自服务器,来自文件ServiceName.xsd

这是我自动生成的Java代理的签名:

public es.xx.UpdateRegisterReturn updateRegister(java.lang.String user, java.lang.String password, java.lang.Integer id1, java.lang.Integer id2, es.xx.OneUpdateRegister[] updates) throws java.rmi.RemoteException{

我是否必须强制将此java参数作为List,即使它是自动生成的,即使它适用于日期和空值?

这个文件(ServiceName1.xsd)是整个服务器解决方案中唯一可以找到Guid类型的地方:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="anyType" nillable="true" type="xs:anyType" />
  <xs:element name="anyURI" nillable="true" type="xs:anyURI" />
  <xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
  <xs:element name="boolean" nillable="true" type="xs:boolean" />
  <xs:element name="byte" nillable="true" type="xs:byte" />
  <xs:element name="dateTime" nillable="true" type="xs:dateTime" />
  <xs:element name="decimal" nillable="true" type="xs:decimal" />
  <xs:element name="double" nillable="true" type="xs:double" />
  <xs:element name="float" nillable="true" type="xs:float" />
  <xs:element name="int" nillable="true" type="xs:int" />
  <xs:element name="long" nillable="true" type="xs:long" />
  <xs:element name="QName" nillable="true" type="xs:QName" />
  <xs:element name="short" nillable="true" type="xs:short" />
  <xs:element name="string" nillable="true" type="xs:string" />
  <xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
  <xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
  <xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
  <xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
  <xs:element name="char" nillable="true" type="tns:char" />
  <xs:simpleType name="char">
    <xs:restriction base="xs:int" />
  </xs:simpleType>
  <xs:element name="duration" nillable="true" type="tns:duration" />
  <xs:simpleType name="duration">
    <xs:restriction base="xs:duration">
      <xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
      <xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
      <xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="guid" nillable="true" type="tns:guid" />
  <xs:simpleType name="guid">
    <xs:restriction base="xs:string">
      <xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
    </xs:restriction>
  </xs:simpleType>
  <xs:attribute name="FactoryType" type="xs:QName" />
</xs:schema>

我猜这是一个自动生成的通用文件。

答案 3 :(得分:0)

抱歉,我刚才意识到两个xsd都来自.net解决方案中的测试客户端!无论如何,他们可能会给出一个线索。

这些是来自Web服务的真实文件:

[ServiceContract(Namespace = Constants.PublicNamespace)]
    public interface InterfaceName
    {

         ///<summary>
        ///</summary>
        ///<param name="user"></param>
        ///<param name="password"></param>
        ///<param name="id1"></param>
        ///<param name="id2"></param>
        ///<param name="updates"></param>
        ///<returns></returns>
        [OperationContract]
        UpdateRegisterReturn UpdateRegister(
            string user,
            string password,
            int id1,
            int id2,
            List<OneUpdateRegister> updates);

        ... {other methods working just fine}    
    }
}

这是OneUpdateRegister类:

     ///<summary>
    ///</summary>
    [DataContract(Namespace = Constants.PublicNamespace)]
    public sealed class OneUpdateRegister
    {
        ///<summary>
        ///</summary>
        [DataMember]
        public RegisterField Field { get; set; }

        ///<summary>
        ///</summary>
        [DataMember]
        public object Value{ get; set; } // this is the problematic data member!
    }