Serialization DataMember (name) override issue
Asked Answered
C

2

12

I am using a DataContractJsonSerializer and have an issue with the DataMember Name.

I made a base class and several derived classes. I need the derived classes because I have different json strings. I want to deserialize the json strings and therefore need different names for the datamembers. I try to change the DataMember name as in the following example:

Baseclass:

[DataContract]
public abstract class BaseClass
{


    [DataMember]
    public virtual string FirstMethod { get; protected set; }

}

Derived class:

[DataContract]
[KnownType(typeof(BaseAccess))]
public class DerivedClass
{


    [DataMember(Name="first_method")]
    public virtual string FirstMethod { get; protected set; }

}

Problem is that when I use a derived class the serialization seems to ignore the given DataMember name. So when I deserialize with the type DerivedClass the serialization seems to take place with the name "FirstMethod" (of the base class) instead of "first_method" (of the derived class). Is it possible to use the DataMember name of the derived class (which is different for several derived classes in my situation).

Another question. I found examples with KnownType added on the base class and added on the derived class. Seems logic to me to do it on the derived class (espcially for inheritance concerns). What is correct?

Capital answered 12/9, 2011 at 19:7 Comment(0)
P
7

I had this same issue. I was using VB.NET and I had to Shadow (or Overload) the property to get WCF to respect the DataMember property in my derived class. In C# you should be able to use the new operator.

public class DerivedClass
{
    [DataMember(Name = "first_method")]
    new public string FirstMethod { get; protected set; }
}
Pedroza answered 13/1, 2012 at 21:44 Comment(1)
Note that to avoid creating two fields in your json, you will need to remove the [DataMember] attribute from the property in the base class.Hurt
E
4

The trick is to specify EmitDefaultValue = false for the base class's virtual data member, and in its implementation in the derived class return default value so the data member is not serialized. In the derived class define another data member with the required name.

[DataContract(Name = "baseclass", Namespace = "")]
[KnownType(typeof(DerivedClass))]
public class BaseClass
{
    [DataMember(Name = "attributes", EmitDefaultValue = false)]
     public virtual SomeType Fields { get; set; }
}

[DataContract(Name = "derivedclass", Namespace = "")]
public class DerivedClass : BaseClass
{
    public override SomeType Fields
    {
        get { return null; }
    }

    [DataMember(Name = "fields")]
    public SomeType DerivedFields
    {
        get { return base.Fields; }
    }
}
Enactment answered 13/11, 2012 at 9:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.