Search code examples
c#jsonserializationenumsnjsonschema

Deserialization of Json to NJsonSchema generated object with enums containing spaces


need your help.

So, i have json schema and i used NJsonSchema.CodeGeneration tool to generate .cs model. I was able of using it to deserialize json into object successfully until the input json contained enum values with spaces in it.

Here is what i am talking about

In schema i have a property like:

...
prop1: {
                enum: [ 'with space', 'withoutspace' ],
            },
...

In generated .cs model i have a corresponding enum:

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "7.10.6235.25398")]
    public enum Some_prop1
    {
        [System.Runtime.Serialization.EnumMember(Value = "with space")]
        With_Space = 0,

        [System.Runtime.Serialization.EnumMember(Value = "withoutspace")]
        Withoutspace= 1,
    }

And here are two input examples: Json 1:

{
    ...
    "prop1": "with space",
    ...
} 

Json 2:

{
    ...
    "prop1": "withoutspace",
    ...
} 

And then i just deserialize it when i need it:

var someModel = Some.FromJson(json);

It works the way it should for a Json 2, but it fails to recognize enum value with space with an error like this:

"Error converting value \"with space\" to type 'com.company.model.Some_prop1'. Path 'prop1', line 7, position 24."

So here is my main question: is there any way to deal with such situation without changing the format of enum in schema?

Small additional question: while investigating i faced one more problem - if i am to use serialization like some.ToJson() my enums will be generated in a way like "prop1": 0, using int< and since json is used as user friendly way to change things, i need it in a way like "prop1": "with space".

Regards, Kanstantsin.


Solution

  • I accidentally found answer myself and hope it would be useful to anyone else too.

    The thing is the default value for enum is int, so while deserializing it tries to have int value of enum or exact name of enum element. But you can force it to understand enum as string first of all:

    ...
    prop1: {
                    type: "string",
                    enum: [ 'with space', 'withoutspace' ],
                },
    ...
    

    So in generated class StringEnumConverter attribute will be used and serialization\deserialization will go the way i wanted it.