Skip to content

Why do I have to define a property when deserializing json with System.Text.Json? #33766

Open
@opcodewriter

Description

@opcodewriter

A simple class with a c-tor like this:

    class Result
    {
        public Result(string error)
        {
        }
    }

and the json:

        var json ="""
            {
                "error": "some error"
            }
            """;
 var result = JsonSerializer.Deserialize<Result>(json, new JsonSerializerOptions(JsonSerializerDefaults.Web));

throws an exception at runtime saying I don't have a property or field defined in the class.

So if I add a property like this:

    class Result
    {
        public string Error { get; }

        public Result(string error)
        {
        }
    }

the exception is not thrown anymore. I correctly receive the "some error" string in the c-tor. However, I don't care to set the property at all.

I know that if I don't want to have a property or field defined in the class, I need to implement a custom JsonConverter<Result>, so how to solve this is not my question.

My question is: Since the deserialization logic is perfectly capable of mapping the error JSON field to the error parameter of the c-tor, why is the property required?

You might ask, why would I NOT want to have a property or a field defined?

Because, in a scenario where the response is a bit more dynamic, I'd like to be able to map the c-tor parameter to something else, without having to have something more complicated like a custom JsonConverter:

        class Result
        {
            // Useless property just to make the deserialization work
            public Dictionary<string, Item> Data { get; }

            public Item Item { get; }

            public Result(Dictionary<string, Item> data)
            {
                Item = data.Values.Single();
            }
        }

        class Item
        {
            public int Id { get; }
            public Item(int id) => Id = id;
        }
{
    "data" : {
         "dynamic_name": { "id" : 1 }
     }
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions