c# - How to make XmlSerializer.Deserialize handle DefaultAttribute properly? -


there seems bug / inconsistency in microsoft xmlserializer: if have property marked system.componentmodel.defaultvalue attribute, not serialized. fair enough - seen expected behavior.

the problem same attribute not respected when deserializing. code below illustrates issue.

question how bypass this? have potentially hundreds of business classes default values used in ui tier (views), default value initialization in constructor not option. has generic. create new default attribute, seems duplicate work. see way override xmlserializer behavior or should use serializer job better?

the example code:

public class defaultvaluetestclass {     [system.componentmodel.defaultvalue(10000)]     public int foo { get; set; } }  [testmethod] public void simpledefaultvaluetest() {     // create object , set property value default     var before = new defaultvaluetestclass();     before.foo = 10000;     // serialize => xml     var serializer = new system.xml.serialization.xmlserializer(typeof(defaultvaluetestclass));     string xml;     using (var stream = new system.io.stringwriter())     {         serializer.serialize(stream, before);         xml = stream.tostring();     }      // deserialize same object     defaultvaluetestclass after;     using (var reader = new system.io.stringreader(xml))     {         after = (defaultvaluetestclass)serializer.deserialize(reader);     }      // before.foo = 10000     // after.foo = 0     assert.areequal(before.foo, after.foo); } 

it your job implement defaults; [defaultvalue] merely says "this default, don't need worry this" - doesn't apply it. applies not xmlserializer, core system.componentmodel api [defaultvalue] belongs (which drives things bold / not-bold in propertygrid, etc)

basically:

public class defaultvaluetestclass {     public defaultvaluetestclass()     {         foo = 10000;     }     [defaultvalue(10000)]     public int foo { get; set; } } 

will work in way expect. if want serialize whether or not particular value, correct implementations is:

public class defaultvaluetestclass {     public defaultvaluetestclass()     {         foo = 10000;     }     public int foo { get; set; } } 

if want preserve [defaultvalue], want serialize, then:

public class defaultvaluetestclass {     [defaultvalue(10000)]     public int foo { get; set; }      [browsable(false), editorbrowsable(editorbrowsablestate.never)]     public bool shouldserializefoo() { return true; } } 

where shouldserialize* pattern system.componentmodel recognised several serializers.


and here's ui code show xmlserializer doing same things ui code (built on system.componentmodel) has done:

using system.componentmodel; using system.windows.forms; static class program {     [system.stathread]     static void main()     {         application.enablevisualstyles();         using (var form = new form())         using (var grid = new propertygrid())         {             grid.dock = dockstyle.fill;             var obj = new defaultvaluetestclass             {   // todo - try other numbers                 // see bold / not bold                 foo = 10000             };             // note in grid value shown not-bold;             // because system.componentmodel saying             // "this property doesn't need serialized"             // - or show more explicitly:             var prop = typedescriptor.getproperties(obj)["foo"];             bool shouldserialize = prop.shouldserializevalue(obj);             // ^^^ false, because of defaultvalueattribute             form.text = shouldserialize.tostring(); // win title              grid.selectedobject = obj;             form.controls.add(grid);             application.run(form);                     }     } }  public class defaultvaluetestclass {     [system.componentmodel.defaultvalue(10000)]     public int foo { get; set; } } 

Comments

Popular posts from this blog

design - Custom Styling Qt Quick Controls -

Unable to remove the www from url on https using .htaccess -