来自XSD的生成代码不接受WCF REST端点中的有效XML

时间:2012-02-10 22:53:30

标签: .net wcf xml-serialization

我有一个XSD,我想定义一个WCF REST端点来接收来自XSD的元素。

我会解释我在做什么

考虑以下架构

<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="dir">
        <xs:complexType>
            <xs:sequence maxOccurs="unbounded" minOccurs="0">
                    <xs:element ref="dir" />
                    <xs:element name="file">
                        <xs:complexType>
                            <xs:attribute name="id" type="xs:integer" />
                            <xs:attribute name="name" type="xs:string" />
                        </xs:complexType>
                    </xs:element>
            </xs:sequence>
            <xs:attribute name="name" type="xs:string" />
        </xs:complexType>
    </xs:element>
</xs:schema>

以下是该架构的一些有效XML

<dir name="root">
  <dir name="foo">
    <file id="12" name="ha" />
    <file id="12" name="ha" />
  </dir>
  <dir name="bar" />
  <file id="12" name="ha" />
  <file id="12" name="ha" />
</dir

如果我使用XSD.exe从架构生成类,我可以在上面创建XML,执行以下操作:

dir foo = new dir{dir1 = new dir[2], name = "root", file = new dirFile[2]};
foo.file[0] = new dirFile{id = "12", name = "ha"};
foo.file[1] = new dirFile { id = "12", name = "ha" };
var file = new dirFile[2];
file[0] = new dirFile { id = "12", name = "ha" };
file[1] = new dirFile { id = "12", name = "ha" };
foo.dir1[0] = new dir { name = "foo", file = file};
foo.dir1[1] = new dir {name = "bar"};

XmlSerializer ser = new XmlSerializer(typeof(dir));
ser.Serialize(Console.Out, foo)

现在假设我想将其用作WCF REST XML端点中的输入

[WebInvoke(UriTemplate = "doit"]
public void doit(dir data) { /* process it */ }

如果我查看该服务的帮助页面,它会显示一个XSD和有效的XML,它与我在XSD中手动定义的完全不同。如果我尝试将之前生成的xml发布到该服务,我会收到以下错误

The exception message is 'Unable to deserialize XML body with root name 'dir' and root namespace '' 

如何定义接收XSD中定义的XML的Web服务?

编辑:这是在REST帮助页面上生成的XSD和XML。

<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/Thomson.Quiz.Web.Services.Models" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/Thomson.Quiz.Web.Services.Models" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="dir">
    <xs:sequence>
      <xs:element name="dir1Field" nillable="true" type="tns:ArrayOfdir" />
      <xs:element name="fileField" nillable="true" type="tns:ArrayOfdirFile" />
      <xs:element name="nameField" nillable="true" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="dir" nillable="true" type="tns:dir" />
  <xs:complexType name="ArrayOfdir">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="dir" nillable="true" type="tns:dir" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ArrayOfdir" nillable="true" type="tns:ArrayOfdir" />
  <xs:complexType name="ArrayOfdirFile">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="dirFile" nillable="true" type="tns:dirFile" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ArrayOfdirFile" nillable="true" type="tns:ArrayOfdirFile" />
  <xs:complexType name="dirFile">
    <xs:sequence>
      <xs:element name="idField" nillable="true" type="xs:string" />
      <xs:element name="nameField" nillable="true" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="dirFile" nillable="true" type="tns:dirFile" />
</xs:schema>

这是xml的例子

<dir xmlns="http://schemas.datacontract.org/2004/07/Thomson.Quiz.Web.Services.Models">
  <dir1Field>
    <dir>
      <dir1Field>
        <dir>
          <dir1Field i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
          <fileField>
            <dirFile>
              <idField>String content</idField>
              <nameField>String content</nameField>
            </dirFile>
            <dirFile>
              <idField>String content</idField>
              <nameField>String content</nameField>
            </dirFile>
          </fileField>
          <nameField>String content</nameField>
        </dir>
        <dir>
          <dir1Field i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
          <fileField>
            <dirFile>
              <idField>String content</idField>
              <nameField>String content</nameField>
            </dirFile>
            <dirFile>
              <idField>String content</idField>
              <nameField>String content</nameField>
            </dirFile>
          </fileField>
          <nameField>String content</nameField>
        </dir>
      </dir1Field>
      <fileField>
        <dirFile>
          <idField>String content</idField>
          <nameField>String content</nameField>
        </dirFile>
        <dirFile>
          <idField>String content</idField>
          <nameField>String content</nameField>
        </dirFile>
      </fileField>
      <nameField>String content</nameField>
    </dir>
    <dir>
      <dir1Field>
        <dir>
          <dir1Field i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
          <fileField>
            <dirFile>
              <idField>String content</idField>
              <nameField>String content</nameField>
            </dirFile>
            <dirFile>
              <idField>String content</idField>
              <nameField>String content</nameField>
            </dirFile>
          </fileField>
          <nameField>String content</nameField>
        </dir>
        <dir>
          <dir1Field i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
          <fileField>
            <dirFile>
              <idField>String content</idField>
              <nameField>String content</nameField>
            </dirFile>
            <dirFile>
              <idField>String content</idField>
              <nameField>String content</nameField>
            </dirFile>
          </fileField>
          <nameField>String content</nameField>
        </dir>
      </dir1Field>
      <fileField>
        <dirFile>
          <idField>String content</idField>
          <nameField>String content</nameField>
        </dirFile>
        <dirFile>
          <idField>String content</idField>
          <nameField>String content</nameField>
        </dirFile>
      </fileField>
      <nameField>String content</nameField>
    </dir>
  </dir1Field>
  <fileField>
    <dirFile>
      <idField>String content</idField>
      <nameField>String content</nameField>
    </dirFile>
    <dirFile>
      <idField>String content</idField>
      <nameField>String content</nameField>
    </dirFile>
  </fileField>
  <nameField>String content</nameField>
</dir

1 个答案:

答案 0 :(得分:0)

我建议您更改正在使用的设计模式。您可能需要考虑改进命名约定以提高可读性。我也会删除多余的使用:

<dir1Field>
    <dir>
      <dir1Field>
        <dir>
您在xml文档中的

。尝试更简单:

<Directory>
  <Files>
    <File>
     <name />
     <id />
    </File>
 </Files>
 </Directory>

尝试使用强类型对象并使用下面概述的相应属性修饰对象。在脚本中实例化本地对象之后, 您可以像上面那样使用var关键字,并像填充任何普通对象属性一样填充字段。在您的情况下,您将不得不考虑创建一个支持对象来保存您需要的所有必要文件信息(名称,ID等)

 /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute(ElementName="Directory")]
    public partial class 
    {

        [System.Xml.Serialization.XmlArrayItemAttribute("File", IsNullable = false)]
        [XmlArray(ElementName="Files")]
        public File[] FileFieldCollection{ get; set; }

    }

根据需要填充FileField对象,你应该没问题。