Connecting Tech Pros Worldwide Help | Site Map

Deserialization and casting problems

Greg Allen
Guest
 
Posts: n/a
#1: Mar 7 '06
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


Rémy
Guest
 
Posts: n/a
#2: Mar 7 '06

re: Deserialization and casting problems



"Greg Allen" <gallen@arrayinc.com> a écrit dans le message de news:
%23QOb2hgQGHA.4312@TK2MSFTNGP12.phx.gbl...[color=blue]
>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
>
>[/color]

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


Greg Allen
Guest
 
Posts: n/a
#3: Mar 7 '06

re: Deserialization and casting problems


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


Josh Twist
Guest
 
Posts: n/a
#4: Mar 8 '06

re: Deserialization and casting problems


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/

Rémy
Guest
 
Posts: n/a
#5: Mar 8 '06

re: Deserialization and casting problems



"Greg Allen" <gallen@arrayinc.com> a écrit dans le message de news:
OTvcIyiQGHA.2276@tk2msftngp13.phx.gbl...[color=blue]
> 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.
>[/color]

There is maybe another problem then ?
You should try to run your code in debugger an try to trace where the
deserialization fails.
[color=blue]
> 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?
>[/color]

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) ...
[color=blue]
> Thanks again,
>
> -- Greg
>
>[/color]


Greg Allen
Guest
 
Posts: n/a
#6: Mar 9 '06

re: Deserialization and casting problems


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


Closed Thread


Similar .NET Framework bytes