views:

134

answers:

3

I would like to create a service that accepts a complex nested type. In a sample asmx file I created:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]
public class ServiceNest : System.Web.Services.WebService
{
   public class Block
   {
      [XmlElement(IsNullable = false)]
      public int number;
   }

   public class Cell
   {
      [XmlElement(IsNullable = false)]
      public Block block;
   }

   public class Head
   {
      [XmlElement(IsNullable = false)]
      public Cell cell;
   }

   public class Nest
   {
      public Head head;
   }

   [WebMethod]
   public void TakeNest(Nest nest)
   {
   }

}

When I view the asmx file in IE the test page shows the example SOAP post request as:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  <soap:Body>
    <TakeNest xmlns="http://schemas.intellicorp.com/livecompare/"&gt;
      <nest>
        <head>
          <cell>
            <block xsi:nil="true" />
          </cell>
        </head>
      </nest>
    </TakeNest>
  </soap:Body>
</soap:Envelope>

It hasn't expanded the <block> into its number member.

Looking at the WSDL, the types all look good. So is this just a limitation of the post demo page creator?

Thanks.

A: 

But those elements ARE null. You need to construct them before they show up otherwise they are just null.

Kevin
Do I have this right: the example POST XML isn't providing these elements and so indicates this with the xsi:nil="true" attribute? I had expected the [XmlElement(IsNullable=false)] to inform consumers of the wsdl that nil elements weren't allowed.
TheArtTrooper
You have the IsNullable on the int within the null block class so the int never has a chance to not be null.
Kevin
I expected that marking all the members as IsNullable = false would tell the client that it wasn't allowed to pass a nil element. At the end of the day the importers in .NET, Java and Ruby correctly read the nested structure. I figure the .NET code that generates the example POST XML just gives up after a certain number of levels.
TheArtTrooper
A: 

As Kevin pointed out the example POST XML indicates that those elements are nil. I should have simply tried to consume the web service. Once I did that I could see that the importer (either .NET, Java or Ruby) correctly created all the types. So really there is no question here after all.

TheArtTrooper
A: 

The .NET code did not give up after a certain number of levels.

If you look at the code generated by "Add Web Reference", you'll find that there's a bool numberSpecified field. Only if the client sets that to true will the number be serialized.

If you look at the XML Schema, you'll see that the number element might be absent. If it were of a reference type, then that could be represented in the client by a null value. Since it's an int, this additional flag is necessary to indicate whether or not to serialize this optional value.

John Saunders