views:

293

answers:

1

I have an XSD, and used the xsd.exe tool to create c# classes. In a webservice I am accepting in the MessageContract an instance of one of these created objects.

The relevant portion of the xsd to this question is here:

<xs:element name="Tasks">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="Task" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="Task"> ... </xs:element>

The xsd created this:

/// <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(Namespace="", IsNullable=false)]
public partial class Tasks {

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Task")]
    public Task[] Task;
}

/// <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(Namespace="", IsNullable=false)]
public partial class Task { ... }

SOAPUI created a soap request from the WSDL that looks like this:

<Tasks>
  <Task>
    <Task>
      .. task data here
    </Task>
  </Task>
</Tasks>

note the extra wrapper element. When trying to run that soap request, I get a deserialization error: Error in line x position y: 'Element' 'WWW' from namespace 'ZZZ' is not expected. Expecting element 'SSS'

After finding the extraneous node in the generated SOAP request, I made my new request look as such:

<Tasks>
  <Task>
    ...task data here
  </Task>
</Task>

Now the deserializer 'works', but in my method the Tasks object contains an empty Task array.

So my question is: Why is the automated request generator creating the wrapper Task object, and why when I remove it am I getting an empty array in my Tasks object?

+1  A: 

You might find your answer if you change the class and property names so they aren't all Task and Tasks.

At a glance though:

<Tasks> <-- the root element for your Tasks class.  public partial class Tasks
  <Task> <-- the Task property of your Tasks class.  public Task[] Task
    <Task> <-- The first serialized task
      .. task data here
    </Task>
    <Task> <-- The second serialized task
      .. second task data here
    </Task
  </Task>
</Tasks>

Another way to look at it is to compare how you'd access a Task within your Task collection of your Tasks class:

var myTasks = new Tasks(); // An instance of your Tasks class
var myTasksTasks = myTasks.Task; // accessing the `Task[]` property of your `Tasks` class
var myFirstTask = myTasks.Task[0]; // accessing the first Task instance within the Task[] array of your Tasks class
STW
What you are saying makes perfect sense. Thanks! However, that leads me to the deserialization error that I get when using correct xml. Inside the <Task> element are several optional elements [minOccurs="0"]. For example: <Accountinfo>, <Artwork>, <Customerinfo>, etc. Omitting any of these elements leads to a deserialization error [Expecting element X]. Do you have suggestions on what might be wrong in this case ?
not off the top of my head. I would suggest testing whether you can serialize and deserialize an object before introducing XML from another source. If you can get a working and non-working sample then asking another question specific to that problem would probably get you an answer.
STW