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

发布于 2025-01-04 16:46:16 字数 7952 浏览 2 评论 0原文

我有一个 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

I have an XSD and I want to define a WCF REST endpoint to recieve an element from the XSD.

I'll explain what I am doing

Consider the following Schema

<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>

Here is some valid XML for that schema

<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

If I use XSD.exe to generate the classes from the schema I am able to create the XML above doing the following:

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)

Now lets say I want to use that as an input in a WCF REST XML endpoint

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

If I look at the help page for that service it shows an XSD and valid XML that are drastically different than what I defined manually in the XSD. If I try posting the xml i generated earlier to that service I get the following error

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

How do I define a web service that receives the XML I defined in the XSD?

EDIT: Here is the XSD and XML generated on the REST help page.

<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>

And here is the example 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你另情深 2025-01-11 16:46:16

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

<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 对象,您应该没问题。

I suggest changing your design pattern you are using. You might want to consider improving your naming conventions for improved readability. I would also remove the redundant use of:

<dir1Field>
    <dir>
      <dir1Field>
        <dir>

which you have in your xml document. Try a simpler:

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

Try to use a strongly typed object and decorate the object with the appropriate attributes as outlined below. Following the instantiation of the local object in your script,
You can use the var keyword as you have done above, and populate the fields as you would any normal object property. In your case you will have to consider creating a backing object to hold all the necessary file information you require (name,id etc.)

 /// <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; }

    }

Populate your FileField object as required and you should be fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文