Note that there are some explanatory texts on larger screens.

plurals
  1. PODeserializing a mixed list of objects from JSON
    primarykey
    data
    text
    <p>I'm using the <code>DataContractJsonSerializer</code> to deserialize objects from an external service. In most cases, this has worked great for me. However, there is one case where I need to deserialize JSON that contains a list of objects that all inherit from the same base class, but there are many different types of objects in that list.</p> <p>I know that it can be done easily by including a list of known types in the serializer's constructor, but I don't have access to the code that generated this JSON service. The types that I'm using will be different from the types used in the service (mostly just the class name and namespace will be different). In other words, the classes that the data was serialized with will not be the same classes that I'll use to deserialize it even though they'll be very similar.</p> <p>With the XML <code>DataContractSerializer</code>, I can pass in a <code>DataContractResolver</code> to map the services types to my own types, but there is no such constructor for the <code>DataContractJsonSerializer</code>. <em>Is there any way to do this?</em> The only options that I've been able to find are: write my own deserializer, or use <a href="http://msdn.microsoft.com/en-us/library/bb943471.aspx" rel="nofollow">Microsoft's JsonObject</a> that isn't tested and "should not be used in production environments."</p> <p>Here is an example:</p> <pre><code>[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&lt;Person&gt;), new Type[] { typeof(Student), typeof(Person) }); // Crashes on this line with the error below var personList = (List&lt;Person&gt;)s.ReadObject(stream); } } } </code></pre> <p>Here is the error mentioned in the comment above:</p> <pre><code>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. </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload