skip to Main Content

I have the following class:

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public class JsonError
{
    [JsonConverter(typeof(StringEnumConverter))]
    public enum Number
    {
        [EnumMember(Value = "0")]
        Pass,
        [EnumMember(Value = "1")]
        Miscalc,
        [EnumMember(Value = "2")]
        ReadError
    }

    public Number ErrorNumber { get; set; }
}

And I try to deserialize this JSON file…

{
  "CriticalErrors": [
    {
      "ErrorNumber": "1"
    },
    {
      "ErrorNumber": "2"
    }
  ]
}

… into this class:

public class TestBehavior
{
    public List<JsonError> CriticalErrors { get; set; } = new List<JsonError>();
}

But I get this error: "The JSON value could not be converted to MyNamespace.JsonError+Number. Path: $.CriticalErrors[0].ErrorNumber | LineNumber: 3 | BytePositionInLine: 24."

Any ideas what could have gone wrong? The values "1" and "2" obviously exist in the enum, and the format seems correct. Unfortunately, the error message does not tell me what exactly has gone wrong, so I am quite lost here.

2

Answers


  1. The issue you’re facing is because the JSON serializer doesn’t know how to convert the string values "1" and "2" into the JsonError.Number enum values. You’ve specified a custom JsonConverter for the ErrorNumber property in your JsonError class, but you haven’t specified this converter while deserializing the JSON into the TestBehavior class.

    To fix this, you need to provide the custom JsonConverter during deserialization. You can do this by using the JsonConverter attribute on the CriticalErrors property in your TestBehavior class.

    Login or Signup to reply.
  2. TL;DR: Your problem is that you are actually using System.Text.Json not Json.NET to deserialize your JSON, and System.Text.Json does not support use of EnumMemberAttribute to specify custom names for enums. (Demo fiddle here).

    To use EnumMemberAttribute you must either:

    1. Switch to Json.NET, or
    2. Use one of the answers from System.Text.Json: How do I specify a custom name for an enum value?.

    How to determine the serializer used?. There are two JSON serializers widely used in .NET Core: System.Text.Json and Json.NET. If an exception is thrown while deserializing JSON, and

    • The exception type comes from the namespace System.Text.Json (e.g. System.Text.Json.JsonException), OR
    • The error message contains information about the LineNumber and BytePositionInLine, e.g. LineNumber: 3 | BytePositionInLine: 24.

    Then the error was generated by System.Text.Json.

    If an exception is thrown and

    • The exception type comes from the namespace Newtonsoft.Json (e.g. Newtonsoft.Json.JsonSerializationException, OR
    • The exception message includes information about the line and position, e.g. line 4, position 28.

    Then the error was generate by Json.NET.

    BytePositionInLine will only ever be reported by System.Text.Json because it deserializes directly from UTF8 byte streams and thus has information about byte positioning. Conversely Json.NET deserializes from UTF16 char streams, and so does not have information about byte positioning, just character positioning.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search