【发布时间】:2011-04-20 13:06:46
【问题描述】:
情况:系统 A 应该公开 SOAP 1.2 Web 服务以供系统 B 调用。为了让 A 知道消息的样子,B 向 A 发送了一个描述消息内容的 XSD。 A 使用 .NET xsd.exe 工具生成了存根,围绕它创建了简单的 web 服务,工作就完成了。
但是;当 B 调用此 Web 服务时,A 拒绝将 SOAP/XML 内容序列化到生成的代理类实例。我意识到这必须归结为在系统 A 的 web 服务端定义序列化的方式,但一直无法准确定位问题所在。
来自 B 的消息是什么样的(匿名) - 失败:
<ns2:Set_Out xmlns:ns2="http://a.a/1.0" xmlns:ns1="http://b.b/1.0" xmlns:ns0="http://c.c">
<Context xmlns="">
<Foo>test</Foo>
<Bar>test</Bar>
...
</Context>
来自测试客户端(基于 WSDL)的测试消息是什么样的 - WORKS:
<Set_Out xmlns="http://a.a/1.0">
<Context xmlns:b="http://schemas.datacontract.org/2004/07/x.x" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:Foo>TEST</b:Foo>
<b:Bar>test</b:Bar>
...
</Context>
当 A 构建的 webservice 接收到 B 的消息时,它根本不序列化消息。代理的对象(例如Context)是null。当它接收到来自测试客户端的消息时,一切都会正确生成。
代理上的序列化属性:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://a.a/1.0")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://a.a/1.0", IsNullable=false)]
[System.ServiceModel.MessageContract]
public partial class Set_Out {
[System.Xml.Serialization.XmlElementAttribute(Namespace="http://a.a/1.0", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] [System.ServiceModel.MessageBodyMember(Order=0)]
public ContextType Context;
...
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://a.a/1.0")]
public partial class ContextType {
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Foo;
我觉得奇怪的事情:
- 为该服务生成 WSDL 时,WSDL 将自己的命名空间添加到 WSDL 定义中(例如,上面示例中的
xmlns:b)。 - WSDL 不尊重代理中定义的
unqualified注释,并且使所有内容都合格。
我尝试了各种注释组合,但似乎没有任何帮助;来自 B 的消息未正确反序列化为 A 生成的代理。任何想法/指针/帮助将不胜感激!
【问题讨论】:
-
注意:上面的 XML 示例是整个消息的摘录,显然这包括更多与 SOAP 相关的内容,但为简洁起见,我将其省略了。
-
为什么要发送 XSD?为什么不直接使用“添加服务参考”?
-
我也有同样的反应,但是我在为一家公司做咨询,这家公司在我的故事中是系统B,所以我避免了冲突,顺从了。
-
其实这是一种颠倒的工作方式;我没有让客户遵守合同 (WSDL),而是修改了合同以使客户工作。有人可能会说这是愚蠢的,而且“做错了”。
-
@pHk:我认为这是不可维护的,不符合标准,并且有悖于您客户的长期利益。
标签: c# .net wcf xml-serialization