强制ASMX代理使用XmlSerializer而不是DataContractSerializer

3
我们的项目需要调用一些外部SOAP服务,这些服务都提供了WSDL数据,但其中很多并不是.NET服务(大部分是用Java编写的)。我们使用wsdl.exe工具生成了一些客户端代理。这个工具完成了它应该做的事情,为我们生成了可供调用的代理。
问题出现在我们尝试使用生成的代理调用服务方法时。为了记录日志,我们截获了所有SOAP请求,发现XML数据与WSDL架构中指定的不同。
例如,如果一个字段叫做“Name”,我们的代理将把它序列化为“nameField”。我猜这是因为名为“Name”的属性使用了名为“nameField”的支持字段。然而,服务端无法解释这种命名规则。
如果我们的ASMX代理使用旧的XmlSerializer,就不会出现这种情况。但由于某些原因,他们选择了DataContractSerializer,这完全搞乱了序列化,并破坏了客户端和服务之间的兼容性。
我的同事们已经开始手动构造XML数据并使用HttpWebRequest类发送请求了。我认为在2011年这是完全不可接受的,因为我们有自动生成代理的工具。
我的问题是:为什么会出现这种情况?为什么我们的代理使用DataContractSerializer,从而忽略了所有xml序列化属性?有没有办法强制它们再次使用XmlSerializer?
我们使用的是.NET 4.0。

你是将这个asmx用作服务引用还是Web引用?因为.NET对它们的处理方式非常不同。 - Darren
作为一个 Web 参考。一定是关于配置的问题,因为当我尝试在干净的解决方案中复制该问题时,一切都正常运行。现在使用变通方法也无妨。 - Vex
1个回答

2
如果你正在使用 WCF,那么默认的序列化方法为 DataContractSerializer。如果类型没有显式指定 [DataContract]/[DataMember] 标记,那么 DataContractSerializer 将使用字段来进行序列化,这似乎就是出现问题的原因。
如果想要使用 XmlSerializer 进行序列化,可以在服务上添加 [XmlSerializerFormat]。详情请参见 MSDN
此外,你也可以尝试给你的类添加 [XmlType] 或者 [XmlRoot] 标记(如果它们还没有被添加)。

正如我所说,我们正在使用外部服务,而我无法决定它们的实现方式。由于某种原因,在序列化期间内部使用了错误的序列化器。我会尽快查看XmlType和XmlRoot属性。谢谢。 - Vex
@Vex 你是如何引用外部服务的?准确地 - Marc Gravell
我获取了WSDL文件,然后在其上运行wsdl.exe并生成代理。无法在VS中引用服务,因为它们位于VPN内部,公司中只有一个人可以访问...他只能将WSDL保存到文件中并传递给我。这与安全有关。 - Vex
@Vex;k - 这听起来应该可以工作;你只是使用常规的asmx,对吧?这很有趣。 - Marc Gravell
是的,常规的asmx。也许有人在配置文件中放了什么东西,这可能会导致问题,我不知道。我希望我有更多时间来调查这个问题,但我们的进度已经落后了,如果我再花更多时间在这上面,我可能会挨骂。他们只想让我手动构建xml数据并使用HttpWebRequest发布它...很糟糕。 - Vex
@vex 这真的很奇怪;您可以检查 web.config 中绑定到 async 的内容,包括在机器级别上,这只是……奇怪。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接