Setting the initial value of a property when using DataContractSerializer
Asked Answered
M

2

10

If I am serializing and later deserializing a class using DataContractSerializer how can I control the initial values of properties that were not serialized?

Consider the Person class below. Its data contract is set to serialize the FirstName and LastName properties but not the IsNew property. I want IsNew to initialize to TRUE whether a new Person is being instantiate as a new instance or being deserialized from a file.

This is easy to do through the constructor, but as I understand it DataContractSerializer does not call the constructor as they could require parameters.

[DataContract(Name="Person")]
public class Person 
{
    [DataMember(Name="FirstName")]
    public string FirstName { get; set; }

    [DataMember(Name = "LastName")]
    public string LastName { get; set; }

    public bool IsNew { get; set; }

    public Person(string first, string last)
    {
        this.FirstName = first;
        this.LastName = last;
        this.IsNew = true;
    }
}
Mullinax answered 28/4, 2010 at 0:1 Comment(0)
F
10

You can use a serialization callback. Add the following method to your Person class:

[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
    this.IsNew = true;
}

Another option is to remove the [DataContract] and [DataMember] attributes. In this case DCSerializer will call your constructor when it deserializes.

Frenzied answered 28/4, 2010 at 0:4 Comment(1)
As Pavel mentions it should be [OnDeserializing] else the value will be overwritten every time rather than just once (when it was missing).Noranorah
B
20

Actually the correct way of doing it is by using the OnDeserializing attribute (notice the "ing" suffix). The method marked with this attribute is called before the member values are deserialized.

Burdened answered 19/5, 2010 at 21:6 Comment(1)
Thank you. Yes, OnDeserializing is the correct way. It allows setting the default value that can be overwritten if the source has the value for the property.Codicil
F
10

You can use a serialization callback. Add the following method to your Person class:

[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
    this.IsNew = true;
}

Another option is to remove the [DataContract] and [DataMember] attributes. In this case DCSerializer will call your constructor when it deserializes.

Frenzied answered 28/4, 2010 at 0:4 Comment(1)
As Pavel mentions it should be [OnDeserializing] else the value will be overwritten every time rather than just once (when it was missing).Noranorah

© 2022 - 2024 — McMap. All rights reserved.