Web Services Quiz: Issue 3 - the Answer

According to Mario’s comment, the problem of Quiz 3 is more an XML than a Web Services one. If you look at the generated schema, you’ll notice that Item.id is of type int:

  <s:complexType name="Item">

  <s:sequence>

  <s:element minOccurs="0" maxOccurs="1" name="componets" type="s0:ArrayOfItem" />

  </s:sequence>

  <s:attributename="Id"type="s:int"use="required"/>

  </s:complexType>

According to the XML schema specification an integer attribute …

· can be defined as optional. By doing so, it can be omitted

· can’t be present but empty (“”)

· must be of type integer

Looking at our SOAP body, there are three occurrences of item types:

  <request xmlns="uri.beatsch.com/issue3">

  <productId="5">

  <componets>

  <ItemId="">

  <componets xsi:nil="true" />

  </Item>

  <Item/>

  </componets>

  </product>

  <amount>30</amount>

  </request>

The first occurrence represents a valid id of 5 but the second one contains an empty string and is therefore invalid. The third item type doesn’t contain an id, although the schema defines this attribute as required.

Therefore, the given XML document isn’t valid according to our schema. Since asmx Web Services don’t check for XML schema validity, the problem manifests itself as a conversion error and not a messaging error. To add schema validation to your Web Services, check out Aaron Skonnard's MSDN article.

Anyway, we are required to accept the described XML document and have to change our XML schema in a way that we can accept empty strings. To do so, we define the attribute as a string. In addition, we remove the use=”required” attribute to implicitly allow missing attributes:

  <s:complexType name="Item">

  <s:sequence>

  <s:element minOccurs="0" maxOccurs="1" name="componets" type="s0:ArrayOfItem" />

  </s:sequence>

  <s:attributename="Id"type="s:string"/>

  </s:complexType>

The corresponding C# class generates the above schema:

 

  public class Item

  {

     [XmlAttribute]

      public string Id;

      public Item[] componets;

  }

Now, we can easily embody our “legacy” XML documents and send them to our Web Service …