接受XmlElement参数的简单格式null

接受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 {

我正在构建一个WCF服务(.NET3.5,IIS托管),以替换旧的ASMX样式的服务。它必须与旧式界面非常兼容,以避免编写调用它的软件的供应商的努力。(他们中的一些人构建了一个简单的XML数据结构,把它放在预先准备好的SOAP“模板”中,然后把它扔给我,我需要接受他们现有的XML结构)

为了与这些客户端调用服务的方式兼容,我必须将操作定义为:

[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服务接受