3

In C# is it possible to serialize object with only the modified values?

For example: I have instance of the Button object bind into the PropertyGrid and I want to serialize that Button object with only the changed properties. In C# what was the best approach to archive this?

cyberj0g
  • 3,707
  • 1
  • 19
  • 34
  • _object with only the changed properties_ - it's unclear what you expect. can you add a code example? – Jossef Harush Kadouri Jun 19 '15 at 06:13
  • How do you find out which properties *have* changed? – nvoigt Jun 19 '15 at 06:19
  • Short answer is no, but have a look at http://stackoverflow.com/questions/9377414/excluding-some-properties-during-serialization-without-changing-the-original-cla – Sarvesh Mishra Jun 19 '15 at 06:22
  • In here changed property means value which is not in it's default value. For example in Button object default value for "Cursor" is "Default". If I changed it to some other value (e.g: SizeAll) I need to get that change into XML. All the other properties which are in it's default values may not be in that XML. – borncon2014 Jun 19 '15 at 06:26

3 Answers3

2

In your own types: yes, you can support this - via the ShouldSerialize* pattern, for example:

public string Name {get;set;}
public bool ShouldSerializeName() { return Name != null; }

However, on external types - it is entirely up to them whether they support this. Note that this will also tell the property-grid which to embolden.

In some cases, [DefaultValue({the default value})] will also work.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

You can iterate object's properties through reflection, compare it's properties with 'fresh' instance, and write down the difference somehow. But you should address many problems if you choose that path, like null handling, serializing non-serializable types, serializing references, etc. Here's just a sketch:

    public static string ChangedPropertiesToXml<T>(T changedObj)
    {
        XmlDocument doc=new XmlDocument();
        XmlNode typeNode = doc.CreateNode(XmlNodeType.Element, typeof (T).Name, "");
        doc.AppendChild(typeNode);
        T templateObj = Activator.CreateInstance<T>();
        foreach (PropertyInfo info in
            typeof (T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
        {
            if (info.CanRead && info.CanWrite)
            {
                object templateValue = info.GetValue(templateObj, null);
                object changedValue = info.GetValue(changedObj, null);
                if (templateValue != null && changedValue != null && !templateValue.Equals(changedValue))
                {
                    XmlElement elem =  doc.CreateElement(info.Name);
                    elem.InnerText = changedValue.ToString();
                    typeNode.AppendChild(elem);
                }
            }
        }
        StringWriter sw=new StringWriter();
        doc.WriteContentTo(new XmlTextWriter(sw));
        return sw.ToString();
    }

A call:

Button b = new Button();
b.Name = "ChangedName";
Console.WriteLine(SaveChangedProperties(b));

An output:

<Button>
   <Name>ChangedName</Name>
</Button>
cyberj0g
  • 3,707
  • 1
  • 19
  • 34
0

Out of the blue, from the information you gave.

You first need to find the dirty properties in the object, you can have another project and track on that when ever there is a change in other properties. or isdirty property for each property or if you can compare with old object to new object.

Then in the ToString() method or you custom serialize method, override to generate the serialized object custom only with the changed properties.

It works for the POCO object, for complex button objects you make have to see how to do it.

its just and idea, more if there is code samples.

Sathya
  • 9
  • 1