Проблема переопределения 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, добавленные в базовый класс и добавленные в производный класс. Кажется логичным для меня сделать это на производном классе (особенно для проблем наследования). Что правильно?
Ответы
Ответ 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; }
}
}