469,951 Members | 2,629 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,951 developers. It's quick & easy.

Deserialization and casting problems

I am consuming a web service and using the generated Reference.cs to access
the service and the objects associated with it.

I have run into a problem where some inherited classes are not being
deserialized. I have verified that the XML being returned by the service
contains the tags I am expecting, but they don't show up in the resulting
object. Here's the relevant portion of the Reference.cs file:

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class FormSection {
[System.Xml.Serialization.XmlElementAttribute("fiel d")]
public FormField[] field;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
[System.Xml.Serialization.XmlIncludeAttribute(typeo f(SelectOneField))]
[System.Xml.Serialization.XmlIncludeAttribute(typeo f(SelectMultipleField))]
[System.Xml.Serialization.XmlIncludeAttribute(typeo f(BooleanField))]
public class FormField {
[System.Xml.Serialization.XmlElementAttribute("valu e")]
public string[] value;
[System.Xml.Serialization.XmlAttributeAttribute()]
public FormFieldType type;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public enum FormFieldType {
boolean,
select1,
selectn,
}
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
[System.Xml.Serialization.XmlIncludeAttribute(typeo f(SelectMultipleField))]
public class SelectOneField : FormField {
[System.Xml.Serialization.XmlArrayItemAttribute("ch oice")]
public Choice[] choices;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class Choice {
public string value;
[System.Xml.Serialization.XmlArrayItemAttribute("fi eld")]
public FormField[] fields;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class SelectMultipleField : SelectOneField {
[System.Xml.Serialization.XmlAttributeAttribute()]
public int maximum_choices;
[System.Xml.Serialization.XmlAttributeAttribute()]
public int minimum_choices;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class BooleanField : FormField {
[System.Xml.Serialization.XmlArrayItemAttribute("fi eld")]
public FormField[] fields;
}

The problem occurs when I get XML like this:

<field type="select1">
<value/>
<choices>
<choice>
<value>17</value>
<fields>
</fields>
</choice>
<choice>
<value>18</value>
<fields>
</fields>
</choice>
</choices>

When this is deserialized, there are no choices! And in code, if I try to
cast
to one of the inherited types, I get an error. Here's the snippet of code:

FormField field = <stuff>.field[0];
switch (field.type)
{
case FormFieldType.boolean:
string[] boolean_value = {"on"};
field.value = boolean_value;
break;
case FormFieldType.select1:
SelectOneField sel1 = (SelectOneField) field;
string[] select1_value = {sel1.choices[0].value};
field.value = select1_value;
}

The cast to SelectOneField fails with "Specified cast is not valid." Why???

Am I doing something wrong? Is there a bug in the service somewhere?

Any help appreciated.

Thanks,

-- Greg
Mar 7 '06 #1
5 2061

"Greg Allen" <ga****@arrayinc.com> a écrit dans le message de news:
%2****************@TK2MSFTNGP12.phx.gbl...
I am consuming a web service and using the generated Reference.cs to access
the service and the objects associated with it.

I have run into a problem where some inherited classes are not being
deserialized. I have verified that the XML being returned by the service
contains the tags I am expecting, but they don't show up in the resulting
object. Here's the relevant portion of the Reference.cs file:
[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class FormSection {
[System.Xml.Serialization.XmlElementAttribute("fiel d")]
public FormField[] field;
}

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
[System.Xml.Serialization.XmlIncludeAttribute(typeo f(SelectOneField))]

[System.Xml.Serialization.XmlIncludeAttribute(typeo f(SelectMultipleField))]
[System.Xml.Serialization.XmlIncludeAttribute(typeo f(BooleanField))]
public class FormField {
[System.Xml.Serialization.XmlElementAttribute("valu e")]
public string[] value;
[System.Xml.Serialization.XmlAttributeAttribute()]
public FormFieldType type;
}

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public enum FormFieldType {
boolean,
select1,
selectn,
}

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]

[System.Xml.Serialization.XmlIncludeAttribute(typeo f(SelectMultipleField))]
public class SelectOneField : FormField {
[System.Xml.Serialization.XmlArrayItemAttribute("ch oice")]
public Choice[] choices;
}

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class Choice {
public string value;
[System.Xml.Serialization.XmlArrayItemAttribute("fi eld")]
public FormField[] fields;
}

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class SelectMultipleField : SelectOneField {
[System.Xml.Serialization.XmlAttributeAttribute()]
public int maximum_choices;
[System.Xml.Serialization.XmlAttributeAttribute()]
public int minimum_choices;
}

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class BooleanField : FormField {
[System.Xml.Serialization.XmlArrayItemAttribute("fi eld")]
public FormField[] fields;
}

The problem occurs when I get XML like this:

<field type="select1">
<value/>
<choices>
<choice>
<value>17</value>
<fields>
</fields>
</choice>
<choice>
<value>18</value>
<fields>
</fields>
</choice>
</choices>

When this is deserialized, there are no choices! And in code, if I try to
cast
to one of the inherited types, I get an error. Here's the snippet of
code:

FormField field = <stuff>.field[0];
switch (field.type)
{
case FormFieldType.boolean:
string[] boolean_value = {"on"};
field.value = boolean_value;
break;
case FormFieldType.select1:
SelectOneField sel1 = (SelectOneField) field;
string[] select1_value = {sel1.choices[0].value};
field.value = select1_value;
}

The cast to SelectOneField fails with "Specified cast is not valid."
Why???

Am I doing something wrong? Is there a bug in the service somewhere?

Any help appreciated.

Thanks,

-- Greg


I guess your WSDL define "choices" as a sequence of "choice".

I have the same problem.

It seems to be a bug in the code generator when he find a sequence
containing only one type: the generated code define an array of "choice",
but nothing to handle the "choices" level.

At run time an exception is raised during de-serialization stating a
"choices" was found where a "choice" was expected, and no deserialization
occurs.
You may try to use a list instead of a sequence (i have not tried that).

I found an ugly workaround: add a second field named "dummy" in the
definition of choices and make this field optional (minOccurs="0").

The generated code is completly different (no more arrays), but now correct.

Rémy
Mar 7 '06 #2
OK, here's the relevant section from the WSDL file:

<s:complexType name="FormSection">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="field"
type="tns:FormField" />
</s:sequence>
</s:complexType>
<s:complexType name="FormField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="value"
type="s:string" />
</s:sequence>
<s:attribute name="type" type="tns:FormFieldType" use="required" />
</s:complexType>
<s:simpleType name="FormFieldType">
<s:restriction base="s:string">
<s:enumeration value="boolean" />
<s:enumeration value="select1" />
<s:enumeration value="selectn" />
</s:restriction>
</s:simpleType>
<s:complexType name="BooleanField">
<s:complexContent mixed="false">
<s:extension base="tns:FormField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="fields"
type="tns:ArrayOfFormField" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
<s:complexType name="ArrayOfFormField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="field"
nillable="true" type="tns:FormField" />
</s:sequence>
</s:complexType>
<s:complexType name="SelectOneField">
<s:complexContent mixed="false">
<s:extension base="tns:FormField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="choices"
type="tns:ArrayOfChoice" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
<s:complexType name="ArrayOfChoice">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="choice"
nillable="true" type="tns:Choice" />
</s:sequence>
</s:complexType>
<s:complexType name="Choice">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="value"
type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="fields"
type="tns:ArrayOfFormField" />
</s:sequence>
</s:complexType>
<s:complexType name="SelectMultipleField">
<s:complexContent mixed="false">
<s:extension base="tns:SelectOneField">
<s:attribute name="maximum_choices" type="s:int" use="required"
/>
<s:attribute name="minimum_choices" type="s:int" use="required"
/>
</s:extension>
</s:complexContent>
</s:complexType>

I put in dummy elements as suggested, like this

<s:element minOccurs="0" maxOccurs="1" name="dummy"
type="s:string" />

wherever there was a sequence with only 1 type. That changed the resulting
file,
but the deserialization still didn't give me the choices.

Am I still missing something? How can I catch the exception during
deserialization that
you describe, to see if I am having the same problem? Is this a known bug?

Thanks again,

-- Greg
Mar 7 '06 #3
The XmlSerializer can deal with choices ok - though the code
interpretation is a little messy:
http://msdn.microsoft.com/msdnmag/is...3/06/XMLFiles/

How did you generate your schema?

Josh
http://www.thejoyofcode.com/

Mar 8 '06 #4

"Greg Allen" <ga****@arrayinc.com> a écrit dans le message de news:
OT**************@tk2msftngp13.phx.gbl...
OK, here's the relevant section from the WSDL file:

<s:complexType name="FormSection">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="field"
type="tns:FormField" />
</s:sequence>
</s:complexType>
<s:complexType name="FormField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="value"
type="s:string" />
</s:sequence>
<s:attribute name="type" type="tns:FormFieldType" use="required" />
</s:complexType>
<s:simpleType name="FormFieldType">
<s:restriction base="s:string">
<s:enumeration value="boolean" />
<s:enumeration value="select1" />
<s:enumeration value="selectn" />
</s:restriction>
</s:simpleType>
<s:complexType name="BooleanField">
<s:complexContent mixed="false">
<s:extension base="tns:FormField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="fields"
type="tns:ArrayOfFormField" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
<s:complexType name="ArrayOfFormField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="field"
nillable="true" type="tns:FormField" />
</s:sequence>
</s:complexType>
<s:complexType name="SelectOneField">
<s:complexContent mixed="false">
<s:extension base="tns:FormField">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="choices"
type="tns:ArrayOfChoice" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
<s:complexType name="ArrayOfChoice">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="choice"
nillable="true" type="tns:Choice" />
</s:sequence>
</s:complexType>
<s:complexType name="Choice">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="value"
type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="fields"
type="tns:ArrayOfFormField" />
</s:sequence>
</s:complexType>
<s:complexType name="SelectMultipleField">
<s:complexContent mixed="false">
<s:extension base="tns:SelectOneField">
<s:attribute name="maximum_choices" type="s:int" use="required"
/>
<s:attribute name="minimum_choices" type="s:int" use="required"
/>
</s:extension>
</s:complexContent>
</s:complexType>

I put in dummy elements as suggested, like this

<s:element minOccurs="0" maxOccurs="1" name="dummy"
type="s:string" />

wherever there was a sequence with only 1 type. That changed the
resulting file,
but the deserialization still didn't give me the choices.

There is maybe another problem then ?
You should try to run your code in debugger an try to trace where the
deserialization fails.
Am I still missing something? How can I catch the exception during
deserialization that
you describe, to see if I am having the same problem? Is this a known
bug?

I have seen the exception when running in debugger. It seems to be catched
before returning to our code.

I don't know if it's a known bug (or a misunderstanding on my side) ...
Thanks again,

-- Greg

Mar 8 '06 #5
I've think I've found a workaround, which may point to the actual problem.

If I change this:

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class FormSection {
[System.Xml.Serialization.XmlElementAttribute("fiel d")]
public FormField[] field;
}

to this:

[System.Xml.Serialization.XmlTypeAttribute(Namespac e="http://mywebservice.com/1.0")]
public class FormSection {
[System.Xml.Serialization.XmlElementAttribute("fiel d")]
public SelectMultipleField[] field;
}

It deserializes correctly!

It seems to have something to do with the inheritance. SelectMultipleField
is
the "top most" in the inheritance chain.

And I don't appear to be getting an exception raised during deserialization.
I've tried
to catch it, but it doesn't appear that anything is being thrown.

Does this maybe shed some light on what the real problem might be?

-- Greg
Mar 9 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Sean McFee | last post: by
1 post views Thread by Linus | last post: by
4 posts views Thread by Mike Sarbu | last post: by
3 posts views Thread by Amadelle | last post: by
3 posts views Thread by parrot toes | last post: by
5 posts views Thread by frustratedWithDotNet | last post: by
7 posts views Thread by PeterW | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.