Я использую DataContractJsonSerializer
для десериализации объектов из внешнего сервиса.В большинстве случаев это отлично сработало для меня.Однако есть один случай, когда мне нужно десериализовать JSON, который содержит список объектов, которые все наследуются от одного и того же базового класса, но в этом списке есть много разных типов объектов.
Я знаю, что он можетсделать это легко, включив список известных типов в конструктор сериализатора, но у меня нет доступа к коду, который сгенерировал этот сервис JSON.Типы, которые я использую, будут отличаться от типов, используемых в сервисе (в основном будут отличаться только имя класса и пространство имен).Другими словами, классы, с которыми данные были сериализованы, не будут теми же классами, которые я буду использовать для десериализации их, даже если они будут очень похожи.
С XML DataContractSerializer
я могупередать DataContractResolver
для сопоставления типов служб моим собственным типам, но для DataContractJsonSerializer
такого конструктора нет. Есть ли способ сделать это? Единственные варианты, которые мне удалось найти: написать свой собственный десериализатор или использовать Microsoft JsonObject , который не тестировался и "долженне может использоваться в производственных средах. "
Вот пример:
[DataContract]
public class Person
{
[DataMember]
public string Name { get; set; }
}
[DataContract]
public class Student : Person
{
[DataMember]
public int StudentId { get; set; }
}
class Program
{
static void Main(string[] args)
{
var jsonStr = "[{\"__type\":\"Student:#UnknownProject\",\"Name\":\"John Smith\",\"StudentId\":1},{\"Name\":\"James Adams\"}]";
using (var stream = new MemoryStream())
{
var writer = new StreamWriter(stream);
writer.Write(jsonStr);
writer.Flush();
stream.Position = 0;
var s = new DataContractJsonSerializer(typeof(List<Person>), new Type[] { typeof(Student), typeof(Person) });
// Crashes on this line with the error below
var personList = (List<Person>)s.ReadObject(stream);
}
}
}
Вот ошибка, упомянутая в комментарии выше:
Element ':item' contains data from a type that maps to the name
'http://schemas.datacontract.org/2004/07/UnknownProject:Student'. The
deserializer has no knowledge of any type that maps to this name. Consider using
a DataContractResolver or add the type corresponding to 'Student' to the list of
known types - for example, by using the KnownTypeAttribute attribute or by adding
it to the list of known types passed to DataContractSerializer.