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

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

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

这是令人困惑的地方,我的消息合同类继承自另一个消息合同类,就像这样

[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. 压缩对象以肥皂格式通过网络发送
  5. 客户端得到响应
  6. 客户端根据“添加服务引用”功能提供的合同进行反序列化。
  7. 客户端设法从响应的基类中反序列化数据,但响应类本身没有任何内容被反序列化。
4

1 回答 1

2

好的,我解决了它,但它真的很糟糕。

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

    [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 元素上手动插入命名空间。特别是那些正常工作的基类!我只是没有看到被调用的方法,因为它被埋得太深了。

于 2013-09-25T15:58:54.537 回答