如何在.Net中的WCF客户端Web服务调用中包含CDATA部分?

时间:2015-06-11 07:02:07

标签: c# .net web-services wcf cdata

我被要求创建一个访问自定义java webservice的wcf客户端,我无法修改。我需要使用webservice方法,如:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <createDocument xmlns="http://www.dummyUrl.com/javaws">
      <version>
        ...
        <metadata>
          <attribute name="ConfigName">ConfigurationTemplateForModuleX</attribute>
          <attribute name="ConfigValue">This is a configuration string</attribute>
        </metadata>
        ...
      </version>
    </createDocument>
  </s:Body>
</s:Envelope>

在属性“ConfigValue”中我通常需要保存字符串,但我还需要能够将整个XML文档保存在节点内,如CDATA:

        ...
        <metadata>
          <attribute name="ConfigName">ConfigurationTemplateForModuleX</attribute>
          <attribute name="ConfigValue">
          <![CDATA[
            <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
            <config>
               <title>Config Template for Module X</title>
               ...
            </config>
          ]]>
          </attribute>
        </metadata>
        ...

我创建了一个对我的Visual Studio项目的服务引用到这个webservice并创建了代理类,我可以使用第一个代码部分中描述的webservice,但问题是我想要包含在CDATA中的CDATA请求是自动编码的,因此不再可用,因为我无法更改目标Web服务:

 &lt;![CDATA[
   &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
   &lt;config&gt;
     &lt;title&gt;Config Template for Module X&lt;/title&gt;
     ...
   &lt;/config&gt;
 ]]&gt;

我需要以某种方式修改XML-Text属性的serilization,或者压缩编码。

您对如何解决此问题有任何想法吗?

2 个答案:

答案 0 :(得分:1)

将XML转换为Base64字符串并进行传输。接收端的简单重新转换将为您提供正确的XML字符串。

答案 1 :(得分:1)

一个不太好的解决方案,但它的工作原理是修改生成的C#服务引用。在类型的部分类中,我看到类似的东西:

import java.util.*;

public class BinaryTree<K extends Comparable<K>, V> implements Iterable<BinaryTree.Entry> {
    private Entry<K, V> root;

    // inOrder iterator
    @Override
    public Iterator<BinaryTree.Entry> iterator() {
        return new InOrderIterator(root);
    }

    class InOrderIterator implements Iterator<BinaryTree.Entry> {
        Entry root;
        Stack<Entry> stack = new Stack<>();

        private void pushLeftChildren(Entry root) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
        }

        public InOrderIterator(Entry root) {
            this.root = root;
            pushLeftChildren(root);
        }

        @Override
        public boolean hasNext() {
            return !stack.isEmpty();
        }

        @Override
        public Entry next() {
            if (!hasNext()) {
                throw new NoSuchElementException("All nodes have been visited!");
            }

            Entry poped = stack.pop();
            pushLeftChildren(poped.right);

            return poped;
        }

        @Override
        public void remove() {

        }
    }

    class Entry<K extends Comparable<K>, V> {
        K key;
        V value;
        Entry<K, V> left;
        Entry<K, V> right;


        Entry(K key, V value, Entry<K, V> left, Entry<K, V> right) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }
}

提示!我使用以下命令行创建了引用,因为生成的代码与Visual Studio服务引用不同:

{{1}}

当我修改&#34;公共字符串值&#34;的参考代码时和&#34;私人字符串valueField&#34;对于类型XmlNode [],可以通过C#代码创建一个XmlNode数组,其中包含一个XmlNode,其中包含Text的内容或CDATA的内容,如:

{{1}}