Сгенерированный код из XSD не принимает допустимый XML в конечной точке REST WCF - PullRequest
0 голосов
/ 11 февраля 2012

У меня есть XSD, и я хочу определить конечную точку REST WCF для получения элемента из 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)

Теперь допустим, что я хочу использовать это в качестве входных данных в конечной точке XML REST WCF

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

Как определить веб-сервис, который получает XML-файл, определенный в XSD?

EDIT: Вот XSD и XML, сгенерированные на странице справки REST.

<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 голосов
/ 14 февраля 2012

Я предлагаю изменить ваш шаблон дизайна, который вы используете. Возможно, вы захотите рассмотреть вопрос об улучшении соглашений об именах для улучшения читабельности. Я также удалил бы избыточное использование:

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

, который у вас есть в вашем XML-документе. Попробуйте попроще:

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

Попробуйте использовать строго типизированный объект и украсьте объект соответствующими атрибутами, как описано ниже. После создания экземпляра локального объекта в вашем скрипте, Вы можете использовать ключевое слово var, как вы делали выше, и заполнять поля так же, как любое обычное свойство объекта. В вашем случае вам нужно будет создать вспомогательный объект для хранения всей необходимой информации о файле (имя, идентификатор и т. Д.)

 /// <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 по мере необходимости, и все будет в порядке.

...