序列化DataMember(名称)重写问题

12

我正在使用DataContractJsonSerializer,并且在DataMember名称上遇到了问题。

我创建了一个基类和多个派生类。我需要派生类,因为我有不同的JSON字符串。我想对JSON字符串进行反序列化,因此需要不同的数据成员名称。我尝试像以下示例中更改DataMember名称:

Baseclass:

[DataContract]
public abstract class BaseClass
{


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

}

派生类:

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


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

}

问题是当我使用派生类时,序列化似乎忽略了给定的DataMember名称。因此,当我使用DerivedClass类型进行反序列化时,序列化似乎会使用基类中的"FirstMethod"名称进行序列化,而不是派生类中的"first_method"名称(在我的情况下,对于几个派生类是不同的)。是否可能使用派生类的DataMember名称(对于我的情况下有多个派生类是不同的)?

另一个问题。我找到了在基类上添加KnownType并在派生类上添加KnownType的示例。在我的理解中,将其添加到派生类上(尤其是考虑到继承)似乎更合适。哪个是正确的?

2个回答

7

我曾经遇到过同样的问题。我在VB.NET中使用了Shadow(或者Overload)这个属性,以便让WCF尊重我派生类中的DataMember属性。在C#中你应该可以使用new操作符。

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

请注意,为了避免在您的JSON中创建两个字段,您需要从基类属性中删除[DataMember]属性。 - Chris Gillum

4

技巧在于为基类的虚拟数据成员指定EmitDefaultValue = false,并在派生类中的实现中返回默认值,这样数据成员就不会被序列化。在派生类中定义另一个具有所需名称的数据成员。

[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; }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接