How to Declare Complex Nested C# Type for Web Serv

2019-08-06 12:55发布

问题:

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/">
  <soap:Body>
    <TakeNest xmlns="http://schemas.intellicorp.com/livecompare/">
      <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.

回答1:

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



回答2:

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.



回答3:

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.