locked
xsd.exe-generated classes do not serialize enum members properly

    Question

  • Hi


    Hi have a class generated by the xsd.exe tool (it's the wix.xsd file describing the WiX wxs file structure - not very important). More of the elements in the xsd file have an attribute of the YesNo simple type defined like this:

      <xs:simpleType name="YesNoType">
        <xs:annotation>
          <xs:documentation>Values of this type will either be "yes" or "no".</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:NMTOKEN">
          <xs:enumeration value="no" />
          <xs:enumeration value="yes" />
        </xs:restriction>
      </xs:simpleType>

    The xsd.exe tool mapped it to a enum:

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.microsoft.com/wix/2006/wi")]
        public enum YesNoType {
           
            /// <remarks/>
            no,
           
            /// <remarks/>
            yes,
        }


    In the code I get to set it this way, for example:

    (New Package).Compressed = YesNoType.yes


    The problem is that when I do serialization:
    m_XmlSerializer.Serialize(p_Stream, m_Wix)

    the respective attributes do not get mapped in at all. They just do not appear in the resulting xml file. Do you have any idea about fixing this ?

    Saturday, December 23, 2006 12:51 AM

Answers

  • Mdeah, I found a workaround for it.

    I changed the name of the properties that wouldn't serialize, those corresponding to enum members, to <prop name>Hack. Then I changed the attribute specifying to serialize the respective property, adding a name for the xml corresponding attribute, the original <prop name>. Nasty, but it works.

    Mihai
    Sunday, January 07, 2007 3:32 AM

All replies

  • The problem seams rather serious, and I still haven't found a fix. In order to make it easier for anybody willing to help (or maybe just confirm that there is a real problem), I uploaded the xsd file here.


    I working on the .NET Framework 2.0. I simply used the xsd.exe tool to generate C# code from the xsd. The result is build into a class library. The library is used from a VB project (trying with another C# project yield the same unfavorable results).

    Al goes wall, until you try to serialize an enumeration member. These just get omitted.

    Any help would be appreciated. Thx.


    Mihai

    Sunday, December 31, 2006 1:35 AM
  • Mdeah, I found a workaround for it.

    I changed the name of the properties that wouldn't serialize, those corresponding to enum members, to <prop name>Hack. Then I changed the attribute specifying to serialize the respective property, adding a name for the xml corresponding attribute, the original <prop name>. Nasty, but it works.

    Mihai
    Sunday, January 07, 2007 3:32 AM
  • Hi Satov,

    I ran into the same problem you have running Framework 1.1.  The damn enum would not serialize.  I have to do the same thing you did and change the name.  Is there a fix for this that you are aware of?  How can I log this as a Bug?

    Cheers!

     

    An Tay

    Monday, March 12, 2007 4:14 PM
  • Hi Satov,

    I am sure if you have figured it out yet, but I just found out that there is a generated property that you have to set to "true" for each enum property inorder for the enum value to be able to serialized.

    Cheers!

     

    An Tay

    Monday, March 12, 2007 7:49 PM
  • Hi. Actually, I haven't been working on that very project for a long time so I don't know the exact solution you are referring to. I still have the same ugly hack in my code. Please provide a little more details on what you did to get it solved cleanly. Thanks.

    Monday, March 12, 2007 8:16 PM
  • Which generated property is that?
    Wednesday, March 21, 2007 10:39 PM
  • Hi Issac,

     

    Say CPlant is your enum variable, then a boolean Attribute CNPlantSpecified is also created for you to set "true" if you wanted it serialized.  The boolean attribute is ignored when serialized.  All of these attributes has the word "Specified" append to it.

     

    {

    ....

    /// <remarks/>

    public PlantType CNPlant;

    /// <remarks/>

    [System.Xml.Serialization.XmlIgnoreAttribute()]

    public bool CNPlantSpecified;

     

    ....

    }

     

    Hope this help.

     

    Cheers!

     

    An Tay

    Wednesday, May 30, 2007 3:57 PM
  • it does! thanks a lot!
    Wednesday, May 30, 2007 4:21 PM
  • Some of the responses to this didn't seem to make much sense. So, I thought it would be prudent to give the simple solution we found: change the Use Requirement in the Properties menu for the attribute to "Required" (i.e. add use="required" to your xs:attribute or xs:element in your schema definition (XSD)).

     

    To reiterate the problem: when attempting to create a Restriction on the value of a node attribute in the XSD Schema Editor (Designer screen shown when editing an XSD), the code generated by xsd.exe properly converts the restrictions to an enum, but the XML generated by serializing the root node's class does not contain the attribute (it's missing--even when the value was set in the class's property field for the attribute).

     

    When it gets down to it, this kind of makes sense. If the use is optional, how are you suppose to deserialize the attribute to an enum (which can't be null) if a value is not given? Actually, Microsoft seems to have handled this. Even though you set the Use Requirement to "Required", xsd.exe doesn't generate code to enforce the requirement. Thus, if you don't assign a value in your class, the attribute will not show up in the serialized XML (as if it were optional). When you go to deserialize the XML, the deserializer simply assigns the first enum value in the list as the value of the property (even though there was none).

     

    Unfortunately, the Default Value property goes grey when you use Restriction. So, keep in mind that you can leave off the attribute as if it were optional, but it will always deserialize to the first enum value, if you do. Since you can't set a default value in the Attribute Field's Properties window, I like to put my default as the first item in the enum list.

     

    For further clarification, my Attribute Field's Properties values look something like this:

    • Data Type: xs: string
    • Derived By: Restriction
    • Base Data Type: xs: string
    • Use Requirement: Required
    • Enumeration: [collection of values to restrict attribute to]

    I found this solution working with BizTalk's Schema template. So, the Properties window described may not be familiar to some of you. However, I'm pretty sure that adding use="required" to your xs:attribute or xs:element definition will give the same successfull result when processed through xsd.exe.

     

    With a little luck, Microsoft will pick up on this and make some tweaks to xsd.exe to either: process the optional usage appropriately; require required usage when using an enumeration; or, allow the setting of the default value. Until then, I hope developers encountering this problem can find this message and make use of it.

    Thursday, February 07, 2008 9:41 PM