7

In .NET Core 3.1 I use System.Text.Json.JsonSerializer to handle my Json objects. When I tried to write an error case when the JsonSerializer.Deserialize<T>() gets a Json string that is of a different type than T I don't get any exception.

Here is a sample code:

using System;
using System.Text.Json;

namespace JsonParsing
{
    class Program
    {
        {
            try
            {
                B b = JsonSerializer.Deserialize<B>( JsonSerializer.Serialize( new A() { a = "asdf" } ) );
                Console.WriteLine( $"b:{b.b}" );
            }
            catch( JsonException ex )
            {
                Console.WriteLine( $"Json error: {ex.Message}" );
            }
        }
    }

    public class A
    {
        public A() {}

        public string a { get; set; }
    }

    public class B
    {
        public B() {}

        public string b { get; set; }

        public C c { get; set; }
    }

    public class C
    {
        public C() {}

        public int c { get; set; }
    }
}

My expectation would be to throw a JsonException as described in Microsoft documentation. What I get instead in the Console.WriteLine( $"b:{b.b}" ) is an object of B with every property containing null.

Am I missing something?

dbc
  • 104,963
  • 20
  • 228
  • 340
SzeliTom
  • 73
  • 1
  • 6
  • 1
    If you are looking for the equivalent of Newtonsoft's [`MissingMemberHandling`](https://www.newtonsoft.com/json/help/html/DeserializeMissingMemberHandling.htm) or [`ItemRequired`](https://stackoverflow.com/a/29660550/3744182) functionalities in [tag:system.text.json], then it doesn't exist. – dbc Jan 15 '21 at 14:16
  • From the [docs](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to#required-properties): *Required properties... System.Text.Json doesn't throw an exception if no value is received for one of the properties of the target type... To make deserialization fail if no property is in the JSON, implement a **custom converter**.* – dbc Jan 15 '21 at 14:17
  • And also from the [docs](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to#missingmemberhandling) *MissingMemberHandling... System.Text.Json ignores extra properties in the JSON, except when you use the [JsonExtensionData] attribute. **There's no workaround for the missing member feature**.* – dbc Jan 15 '21 at 14:19
  • Ok I got it. Thanks for the help – SzeliTom Jan 15 '21 at 14:23

1 Answers1

4

Based on documentation, the excpetion was thrown if :

The JSON is invalid.
-or-
TValue is not compatible with the JSON.
-or-
A value could not be read from the reader.

The code :

JsonSerializer.Serialize( new A { a = "asdf" } )

Geneate json like :

{ "a", "asdf" }

So no exception was thrown because :
1 - The Json is valid.
2 - B is compatible with this Json, it's like {}, b and c are not exist in the json, so will be null after deserialization.
3 - The reader can read the Json.

The exception will be raised if the json for example is like : "" or []

I hope you find this helpful.

Mohammed Sajid
  • 4,778
  • 2
  • 15
  • 20
  • I misinterpreted the _compatible_ word here. Thanks for the clarification! – SzeliTom Jan 15 '21 at 14:24
  • Word compatible here is awfully stretched out. This should clearly throw an exception, imho. Testing it right now on one of my entities, where I am able to successfully deserialize it to type `Exception` !! This should not happen, again imho. Seems like if the objects are of same `JsonValueKind`, they will always be deserialized without throwing... – Manus Abyss Feb 08 '23 at 10:51