Pradeep
Pradeep

Reputation: 40

After deserializing some values getting in Protobuff-net

In our .NET application, the classes are generated dynamically and it has multi-level inheritance.

We are facing problems - after deserializing ProtoContract class some values are set to null (we are using protobuf-net version 3.2.30 on .NET 6).

Here is our sample class structure, we can't use [ProtoInclude()] sue we have so many classes and these are generated dynamically from different tool

[DataContract]
[Serializable]
[ProtoContract]
public partial class Person : TrackingObject
{
    [DataMember(Name = "A1")]
    [ProtoMember(1)]
    internal int __id_person;

    [XmlIgnore]
    public int ID_PERSON
    {
        get
        {
            return __id_person;
        }
        set
        {
            if (value != __id_person)
            {
                __id_person = value;
                SetPrimaryKeyId(value);
            }
        }
    }

    [DataMember(Name = "A2")]
    [ProtoMember(2)] 
    public string NAME { get; set; }
   
    [DataMember(Name = "A3")]
    [ProtoMember(3)] 
    public DateTime DOB { get; set; }
}

[DataContract]
[Serializable]
[ProtoContract]
public class TrackingObject : PrimaryKeyObject
{
    [DataMember(Name = "Z1")]
    [ProtoMember(1)]
    internal HashSet<string> __propertyChangedList;
    [DataMember(Name = "Z2")]
    [ProtoMember(2)]
    internal EntityStateFlag __entityState;
    public TrackingObject()
        : base()
    {
    }

    [OnDeserialized]
    private void UpdateEntityState()
    {
        if (this.EntityState == EntityStateFlag.Detached)
            __entityState = EntityStateFlag.Unchanged;
    }

    [XmlIgnore]
    public EntityStateFlag EntityState
    {
        get
        {
            if (__entityState == 0)
                __entityState = EntityStateFlag.Detached;
            return __entityState;
        }
        set
        {
            if (value != __entityState)
            {
                __entityState = value;
                if ((value == EntityStateFlag.Unchanged || value == EntityStateFlag.Detached) && __propertyChangedList != null)
                    __propertyChangedList = null;
            }
        }
    }
}

[DataContract]
[Serializable]
[ProtoContract]
public class PrimaryKeyObject
{
    [DataMember(Name = "Y1")]
    [ProtoMember(1)]
    internal int? __primaryKeyId;
    [XmlIgnore]
    public int? PrimaryKeyId
    {
        get
        {
            return __primaryKeyId;
        }
    }

    public void SetPrimaryKeyId(int? primaryKeyId)
    {
        __primaryKeyId = primaryKeyId;
    }
}

We are using the code as shown below - serializer and deserializer

internal class Program
{
    static void Main(string[] args)
    {
        var person = new Person()
        {
            ID_PERSON = 1,
            NAME = "Abc",
            DOB = DateTime.Now.AddYears(-10)
        };

        MemoryStream objectSerializer = new MemoryStream();
        objectSerializer.Seek(0, SeekOrigin.Begin);
        WriteNext(objectSerializer, person);

        objectSerializer.Seek(0, SeekOrigin.Begin);
        var i1 = DeSerialized<Person>(objectSerializer);
    }

    static readonly Dictionary<int, Type> typeLookup = new Dictionary<int, Type>();

    static void WriteNext(Stream stream, object obj)
    {
        Type type = obj.GetType();

        if (!typeLookup.ContainsValue(type))
        {
            var key = typeLookup.Count > 0 ? typeLookup.Max(i => i.Key) : 0;
            typeLookup.Add(key + 1, type);

            int field = typeLookup.Single(pair => pair.Value == type).Key;
            Serializer.NonGeneric.SerializeWithLengthPrefix(stream, obj, PrefixStyle.Base128, field);
        }
    }

    static T DeSerialized<T>(Stream stream)
    {
        object obj;

        if (Serializer.NonGeneric.TryDeserializeWithLengthPrefix(stream, PrefixStyle.Base128, field => typeLookup[field], out obj))
        {
            if (obj.GetType() == typeof(T))
                return (T)obj;
        }

        return default(T);
    }
}

We set primary key when we initialize a Person class and after deserializing, we are getting PrimaryKeyId as null and also we won't call OnDeserialized automatically.

looking for some suggestions on this, thanks in advance.

Multilevel field value should not be lost after deserializing and how to call OnDeserialized for parent class?

Upvotes: 0

Views: 75

Answers (0)

Related Questions