Serialize only changed properties of an object

In C #, is it possible to serialize an object with only changed values?

For example: I have a binding instance of a Button object in a PropertyGrid and I want to serialize this Button object with only changed properties. In C #, what was the best approach to archiving?

+3


source to share


3 answers


You can iterate over the properties of an object through reflection, compare its properties to a "fresh" instance, and somehow record the difference. But you have to solve many problems if you choose this path, such as null

processing, 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();
    }

      

Call:



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

      

Output:

<Button>
   <Name>ChangedName</Name>
</Button>

      

+1


source


In your own types: yes, you can support this - with a template ShouldSerialize*

like:

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

      



However, on external types, it entirely depends on whether they support it. Note that this will also point to the grid property that will spoof.

It also works in some cases [DefaultValue({the default value})]

.

+2


source


From blue, from the information you provided.

First you need to find the dirty properties in the object, you can have a different project and track when other properties change ever. or isdirty for each property or if you can compare the old object with the new object.

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

It works for POCO object, for complex button objects you should see how.

its fairness and idea, more if there are code samples.

0


source







All Articles