接受XmlElement参数的简单格式null
我正在构建一个WCF服务(.NET3.5,IIS托管),以替换旧的ASMX样式的服务。它必须与旧式界面非常兼容,以避免编写调用它的软件的供应商的努力。(他们中的一些人构建了一个简单的XML数据结构,把它放在预先准备好的SOAP“模板”中,然后把它扔给我,我需要接受他们现有的XML结构) 为了与这些客户端调用服务的方式兼容,我必须将操作定义为:接受XmlElement参数的简单格式null,xml,wcf,null,asmx,Xml,Wcf,Null,Asmx,我正在构建一个WCF服务(.NET3.5,IIS托管),以替换旧的ASMX样式的服务。它必须与旧式界面非常兼容,以避免编写调用它的软件的供应商的努力。(他们中的一些人构建了一个简单的XML数据结构,把它放在预先准备好的SOAP“模板”中,然后把它扔给我,我需要接受他们现有的XML结构) 为了与这些客户端调用服务的方式兼容,我必须将操作定义为: [ServiceContract(Namespace = "urn:namespacex")] public interface IServices {
[ServiceContract(Namespace = "urn:namespacex")]
public interface IServices
{
[OperationContract]
System.Xml.XmlElement OperationA(int parmB, System.Xml.XmlElement parmC);
}
i、 e.参数在OperationContract中,而不是拉入DataContract中的单独DataMember元素中。此处使用的XmlElement替换旧ASMX服务中使用的XmlNode参数
它的实施方式如下:
[ServiceBehavior(Namespace = "urn:namespacey")]
public class TheService : IServices
{
public System.Xml.XmlElement OperationA(int parmB, System.Xml.XmlElement parmC)
{
... code to handle call
}
}
它很好用。。。当有数据要发送时
我遇到的问题是parmC输入为null时,这是允许的。有时有数据,有时没有。一个调用方在SOAP消息中为空parmC发送此消息:
<parmC/>
i、 e.一个简单的空XML元素
这将从WCF引发以下错误:
应为状态“元素”。。遇到名为的“EndElement”
“parmC”,命名空间“urn:namespacex”
因此,它似乎不喜欢简单的null元素输入。(如果服务中确实有一些数据,则该服务可以正常工作。)
跟踪我自己的测试调用方(在parmC参数中使用或不使用信息),我可以看到对于null,我的(.Net WCF)测试仪正在发送:
<parmC xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:nil="true"/>
尝试1:
为了寻求帮助,我注意到了“[XmlSerializerFormat]”属性,通过不使用较新的数据契约序列化程序,该属性可以使服务更像旧式的ASMX。然后,我的测试调用方(.Net,WCF)将不为空值发送任何内容。但是这个客户端仍然会收到一个错误,尽管它现在是一条与该元素不同的消息:
没有打开相应的起始元素
尝试2:
然后我想起了原始ASMX服务的最旧版本,它使用一个字符串来接受该数据。(它将该字符串加载到操作处理程序内的XML对象服务器端)。因此,我更改了契约和操作,将parmC定义为字符串,而不是XmlElement
突然间,服务接受了各种形式的空parmC。(使用一个快速测试应用程序,将原始SOAP发布到我的服务中,这样我就可以模拟这些供应商所做的事情)
但是-如果其中确实有数据,则会失败,原因是:
反序列化操作的请求消息正文时出错
“OperatonA.”-->System.InvalidOperationException:出现错误
在XML文档(99,99)中。-->System.Xml.XmlException:结束元素
应为命名空间“urn:namespacex”中的“parmC”。找到元素“a”
来自命名空间“”
(在parmC中发送XML数据时,SOAP中的情况如下:
<parmC>
<a xmlns="">bbb</a>
</parmC>
bbb
)
显然,在这种情况下,它不希望在字符串(a元素)中找到XML;但这曾经在ASMX中起作用,因此“值得一试”
因此,我找不到允许将XML数据发送到服务的组合设置,同时也允许客户端样式的空数据或空数据 我必须实现自定义反序列化程序吗?有什么地方可以帮忙吗 (到目前为止,我已经成功地将所有与WCF相关的内容完全保留在配置中,如果可以的话,我希望保持这种状态。) 总而言之,我需要一个WCF服务,它可以处理以下任何一种情况:
<s:Body>
<OperationA xmlns="urn:namespacex">
<parmB>1</parmB>
<parmC> { this works fine }
<a xmlns="">
<b>bbb</b>
</a>
</parmC>
</OperationA>
</s:Body>
<s:Body>
<OperationA xmlns="urn:namespacex">
<parmB>1</parmB>
<parmC/> { I need this to be accepted }
</OperationA>
</s:Body>
1.
{这很好用}
bbb
1.
{我需要这个被接受}
您提供的两个选项的XML不等效。这两者之间有一个非常微妙的区别,这可能是你的问题的原因。带有
的选项将元素a及其子元素设置为没有默认的XML命名空间。另一个选项(“null”参数选项)不包含默认XML名称空间从“urn:namespacex”到“”的“重新定义”,因此当反序列化过程解析元素
的parmC时,它找不到它。如果您仔细阅读异常消息,它实际上是在告诉您这一点
至于如何支持这两种方案,请尝试让您的客户机发送此内容,而不是他们现在发送的内容:
<parmC>
<a xmlns="">
<b />
</a>
</parmC>
或者可能:
<parmC>
<a xmlns="" />
</parmC>
您提供的两个选项的XML不等效。这两者之间有一个非常微妙的区别,这可能是你的问题的原因。带有
的选项将元素a及其子元素设置为没有默认的XML命名空间。另一个选项(“null”参数选项)不包含默认XML名称空间从“urn:namespacex”到“”的“重新定义”,因此当反序列化过程解析元素
的parmC时,它找不到它。如果您仔细阅读异常消息,它实际上是在告诉您这一点
至于如何支持这两种方案,请尝试让您的客户机发送此内容,而不是他们现在发送的内容:
<parmC>
<a xmlns="">
<b />
</a>
</parmC>
或者可能:
<parmC>
<a xmlns="" />
</parmC>
请不要在回答前加上“WCF”之类的前缀。这就是标签的作用。请不要在答案前加上“WCF”之类的前缀。这就是标签的用途。谢谢。该元素没有在契约中定义,它只是发送到参数parmC的XML数据在线路上的一个示例。当parmC被定义为XmlElement时,这个函数就起作用了。我相信,上的空名称空间本质上让desrialiser注意到它不是定义的消息格式的一部分,这就是为什么它不会抱怨意外。问题在于parmC为空时。这两种格式在旧的ASMXWeb服务中工作,所以我只是在寻找一种方式让WCF服务接受