Microsoft KB Archive/325691

= PRB: XML Serialization: System.Xml.XmlSerializer Does Not Serialize Default Values =

Article ID: 325691

Article Last Modified on 5/9/2007

-

APPLIES TO


 * Microsoft .NET Framework 1.0

-



This article was previously published under Q325691



SYMPTOMS
System.Xml.XmlSerializer does not serialize default values that are present in the XML schemas (XSD). For example, if the schema contains the following line, the default value of False for the   element is not serialized: 



CAUSE
The following is an excerpt from the Microsoft .NET Framework SDK documentation:

If the value assigned to a field or property is equal to the default value for that field or property, the XmlSerializer will not serialize the value to the XML-instance.

For more information about this behavior, see the following Microsoft Developer Network (MSDN) Web site:

XmlAttributes.XmlDefaultValue Property

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlserializationxmlattributesclassxmldefaultvaluetopic.asp



RESOLUTION
One of following two workarounds can be used to resolve this problem:
 * 1) After the Xsd.exe file generates the classes from the schemas, manually comment out or remove all of the [System.ComponentModel.DefaultValueAttribute(&quot;myFieldName&quot;)] attributes from the class files.
 * 2) Use the class constructors instead of the schema to assign the default values.



STATUS
This behavior is by design.

Microsoft plans to change this behavior in the next major version release of the .NET Framework.



MORE INFORMATION
This behavior introduces limitations such as the following:
 * The structure (the schema or the class) must always be passed with the data.
 * To recover the default value from the schema, it must be parsed each time.

Steps to Reproduce the Behavior
  Use a text editor such as Notepad to save the following as Q325691.xsd:  

     <xsd:element name=&quot;boolT&quot; type=&quot;xsd:boolean&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; default=&quot;true&quot; /> <xsd:element name=&quot;boolF&quot; type=&quot;xsd:boolean&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; default=&quot;false&quot; /> <xsd:element name=&quot;decimalval&quot; type=&quot;xsd:decimal&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; default=&quot;10&quot; /> </xsd:sequence> </xsd:complexType> </xsd:schema> </li> <li> Use the Xsd.exe utility to create a Microsoft .NET class for this schema. To do this, click Start, click Programs, click Microsoft Visual Studio .NET, click Visual Studio .NET Tools, and then click Visual Studio .NET Command Prompt to open the Visual Studio .NET command window, and then run a command similar to the following:

xsd.exe /c /n:TestDefaultNS C:\myDir\Q325691.xsd /out:C:\myDir

The /c switch indicates class creation, the /out switch indicates the output directory, and the /n switch specifies the namespace to use when generating the class. The output will look similar to the following: Microsoft (R) Xml Schemas/DataTypes support utility [Microsoft (R) .NET Framework, Version 1.0.3705.0] Copyright (C) Microsoft Corporation 1998-2001. All rights reserved.

Writing file 'C:\myDir\Q325691.cs'. This creates a Visual C# class named Q325691.cs. Its content looks like the following: //-- // //    This code was generated by a tool. //    Runtime Version: 1.0.3705.0 // //    Changes to this file may cause incorrect behavior and will be lost if //     the code is regenerated. // //--

// // This source code was auto-generated by xsd, Version=1.0.3705.0. // namespace TestDefaultNS { using System.Xml.Serialization; ///    [System.Xml.Serialization.XmlTypeAttribute(Namespace=&quot;urn:myNS&quot;)] [System.Xml.Serialization.XmlRootAttribute(&quot;testDefault&quot;, Namespace=&quot;urn:myNS&quot;, IsNullable=false)] public class TestDefault { ///        public string str; ///        [System.ComponentModel.DefaultValueAttribute(&quot;Default Value&quot;)] public string strDefault = &quot;Default Value&quot;; ///        [System.ComponentModel.DefaultValueAttribute(true)] public bool boolT = true; ///        [System.ComponentModel.DefaultValueAttribute(false)] public bool boolF = false; ///        [System.ComponentModel.DefaultValueAttribute(typeof(System.Decimal), &quot;10&quot;)] public System.Decimal decimalval = ((System.Decimal)(10m)); }

} </li> <li> Create a new Microsoft Visual C# .NET console application named Q325691, and then paste the following in the Class1.cs file: using System; using System.IO; using System.Text; using System.Xml.Serialization; using TestDefaultNS;

namespace Q325691 {  class Class1 {     [STAThread] static void Main(string[] args) {        try {           // Create a new class instance for serialization. TestDefault td = new TestDefault; XmlSerializer serializer = new XmlSerializer(typeof(TestDefault), &quot;urn:myNS&quot;); // Serialize the object and display the output. StringBuilder sb = new StringBuilder; StringWriter sw = new StringWriter(sb); serializer.Serialize(sw, td); Console.Write(sw.ToString + &quot;\n\n&quot;); }        catch (Exception ex) {           Console.Write(ex.Message + &quot;\r\n&quot; + ex.InnerException.Message); }     }   }

} </li> <li>On the Project menu, click Add Existing Item to add the Q325691.cs class file to the project.</li> <li> Compile and run the application. The output will look similar to the following. Note that the elements are not serialized: <?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?> <testDefault xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;urn:myNS&quot; /> </li> <li> Modify Q325691.cs to try the first workaround, as follows. Note that the lines that specify DefaultValueAttribute are commented out: //-- // //    This code was generated by a tool. //    Runtime Version: 1.0.3705.0 // //    Changes to this file may cause incorrect behavior and will be lost if //     the code is regenerated. // //--

// // This source code was auto-generated by xsd, Version=1.0.3705.0. // namespace TestDefaultNS { using System.Xml.Serialization; ///    [System.Xml.Serialization.XmlTypeAttribute(Namespace=&quot;urn:myNS&quot;)] [System.Xml.Serialization.XmlRootAttribute(&quot;testDefault&quot;, Namespace=&quot;urn:myNS&quot;, IsNullable=false)] public class TestDefault { ///        public string str; ///        //[System.ComponentModel.DefaultValueAttribute(&quot;Default Value&quot;)] public string strDefault = &quot;Default Value&quot;; ///        //[System.ComponentModel.DefaultValueAttribute(true)] public bool boolT = true; ///        //[System.ComponentModel.DefaultValueAttribute(false)] public bool boolF = false; ///        //[System.ComponentModel.DefaultValueAttribute(typeof(System.Decimal), &quot;10&quot;)] public System.Decimal decimalval = ((System.Decimal)(10m)); } }                   </li> <li> Compile and run the application. The output will look similar to the following. Note that the elements are serialized: <?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?> <testDefault xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;urn:myNS&quot;> <strDefault>Default Value</strDefault> <boolT>true</boolT> <boolF>false</boolF> 10 </testDefault> </li></ol>

<div class="references_section">