Skip to content

Strict mode for constructor-based deserialisation #135

@drewnoakes

Description

@drewnoakes

The support for deserialising via constructor calls is really great!

I need the ability to make this deserialisation more strict in many cases, both where properties are missing, or where extra properties exist. Currently missing properties are filled with default(T).

An example:

public class Foo
{
    public int A { get; }
    public string B { get; }

    public Foo(int a, string b) { A = a; B = b; }
}

I am using SerializationMethod.Map in the SerializationContext.

{ "A": 1, "B": "Bar" } --> new Foo(1, "Bar")

{ "A": 1 } --> new Foo(1, null)

{ "B": "Bar" } --> new Foo(0, "Bar")

In many cases, receiving an incomplete message is a failure, and should throw. Can we add a new property to SerializationContext that allows making this strict? Perhaps:

new SerializationContext
{
    ConstructorDeserialisationOptions = ConstructorDeserialisationOptions.Strict
};

[Flags]
enum ConstructorDeserialisationOptions
{
    None = 0,
    ThrowOnMissingProperty = 1 << 0,
    ThrowOnUnexpectedProperty = 1 << 1,
    ThrowOnIncorrectPropertyType = 1 << 2,
    Strict = ThrowOnMissingProperty | ThrowOnUnexpectedProperty | ThrowOnIncorrectPropertyType
}

The current behaviour could be kept under None, which would be the default to avoid breaking changes for existing users.

Note that if the user wants null (or some other default value) in the case where a property in not in the incoming map, they can specify a default value for the constructor parameter:

    public Foo(int a = 123, string b = null) { A = a; B = b; }

With this, even in strict mode, you get { } --> new Foo(123, null).

This would be very useful on my current project and there's a good chance I could work on the implementation if you felt this feature could be merged and could provide some advice on where to start. Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequires or request to feature enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions