ASMX Web服务的反序列化部分失败

时间:2013-09-25 00:06:56

标签: c# xml-serialization asmx datacontract

  • 请注意我正在修改现有服务以添加额外的数据,我无法更改服务的结构或客户端。我知道ASMX已经过时,并且没有使用最佳实践。

我遇到了一个非常奇怪的问题,我无法弄清楚如何让它正常工作。我有一个ASMX Web服务(我知道它已经过时了,我无法改变它)这需要一个响应并使用zip压缩进行压缩。然后通过SOAP将它传递给客户端,客户端获取流并对其进行解压缩,并使用“添加服务引用”和XMLSerializer创建的契约来反序列化对象。

我遇到的问题是它无法正确反序列化对象。压缩之前和解压缩后的XML看起来完全相同,但似乎Web服务忽略了我的参数的排序。我已经尝试了[DataMember],[MessageBodyMember],[XmlElement],[MessageHeader]以及正确的排序参数和MustUnderstand但它似乎总是将元素放在XML的底部。

这是令人困惑的,我的messagecontract类继承自另一个消息契约类,如此

[MessageContract(IsWrapped = true)]
public class MyClass : MyBaseContract{}

基本联系人中的元素每次反序列化都很好,即使我改变它们就可以正常工作。那里的元素根本不包含任何排序,它们只是起作用。

这是我的反序列化代码。

using (MemoryStream stream = new MemoryStream(data))
        {
            XDocument document = XDocument.Load(stream);

            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(type);
            System.Xml.XmlReader read = System.Xml.XmlReader.Create(new System.IO.StringReader(document.ToString()));

            object o = serializer.Deserialize(read);

            return o;
        }

这是序列化代码:

        XmlSerializer xs = new XmlSerializer(value.GetType());
        MemoryStream stream = new MemoryStream();
        xs.Serialize(stream, value);
        stream.Position = 0;
        StreamReader sr = new StreamReader(stream);
        return sr.ReadToEnd();

所以这是我的代码采取的步骤

  1. 致电网络服务
  2. Web服务调用helper并返回响应对象
  3. 压缩响应对象
  4. 压缩对象通过网络以soap格式发送
  5. 客户获得回复
  6. 客户端根据“添加服务引用”功能提供的合同进行反序列化。
  7. 客户端设法从响应的基类反序列化数据,但响应类本身没有任何反序列化。

1 个答案:

答案 0 :(得分:2)

好的,我解决了它,但真的很棘手。

发生的事情是“添加服务引用”生成的代码包含名称空间

    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://myservice.com")]

但是,您可以手动执行的XML序列化不会在生成的XML中的任何位置包含命名空间。如果我指定使用此代码,XML序列化程序将中断。

   [MessageContract(IsWrapped = true,WrapperNamespace="http://myservice.com")]

使其正常工作的唯一方法是将指定命名空间的行从生成的代码添加回合同类,如此。

[XmlType(Namespace="http://myservice.com")]
public class MyContract {}

在此添加之后,所有生成的xml将在每个元素中包含完整的命名空间,并且反序列化器将正常运行。为什么它在命名空间的WCF上打破我不知道。它适用于其他WCF主义。

它首先部分工作的原因是前一个开发人员添加了一个方法,该方法在客户端的某些XML元素上手动插入命名空间。特别是那些正常工作的基类!我只是没有看到被调用的方法,因为它埋藏得如此之深。