Подтвердить что ты не робот

Проблема переопределения DataMember (name)

Я использую 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. Поэтому, когда я deserialize с типом DerivedClass, сериализация, похоже, имеет место с именем "FirstMethod" (базового класса) вместо "first_method" (производного класса). Можно ли использовать имя DataMember производного класса (что отличается для нескольких производных классов в моей ситуации).

Другой вопрос. Я нашел примеры с KnownType, добавленные в базовый класс и добавленные в производный класс. Кажется логичным для меня сделать это на производном классе (особенно для проблем наследования). Что правильно?

4b9b3361

Ответ 1

У меня была такая же проблема. Я использовал VB.NET, и мне пришлось переопределить свойство Shadow (или Overload), чтобы заставить WCF уважать свойство DataMember в моем производном классе. В С# вы должны использовать новый оператор.

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

Ответ 2

Фокус в том, чтобы указать 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; }
    }
}