简体   繁体   中英

Enum deserialization with Newtonsoft.Json

Hello I want to deserialize a class and in this class is a enum value:

[JsonConverter(typeof(StringEnumConverter))]
public enum MessageType {
    Verify, 
    Disconnect,
}

[Serializable]
public class SocketMessage {
    public Dictionary<String, String> Header { get; private set; }
    public MessageType MessageType { get; private set; }

    public SocketMessage(MessageType type) {
        Header = new Dictionary<String, String>();
        MessageType = type;
    }

    public void AddHeaderData(String key, String data) {
        Header.Add(key, data);
    }

    public byte[] ToJSONBytes() {
        String json = JsonConvert.SerializeObject(this);
        return Encoding.UTF8.GetBytes(json);
    }

    public static SocketMessage FromJSONBytes(byte[] json) {
        String s = Encoding.UTF8.GetString(json);
        return JsonConvert.DeserializeObject<SocketMessage>(s);
    }
}

The dictionary will be correctly deserialized but the enum always get his default value >verify< the json looks like this: {"Header":{"Test":"Test"},"MessageType":"Disconnect"}

I really don't understand why it happens

I appreciate any help!

It does not work as you have it because of the private set on the MessageType property. So the getter is public and so it serializes fine, but when it comes to deserialize, it is ignored. There are a few possible solutions to this.

  1. Use a public setter for MessageType . There is probably a reason why you wanted to use a private setter in the first place though, so this maybe not for you.
  2. Apply the JsonProperty attribute to the MessageType property:
[JsonProperty]
public MessageType MessageType { get; private set; }
  1. Change the constructor parameter name to messageType instead of type , so it matches the serialized name:
public SocketMessage(MessageType messageType)
{
     Header = new Dictionary<String, String>();
     MessageType = messageType;
}

Why was it not a problem for Header ? This is because it is new'ed up in the constructor. The constructor is called in deserialization, so this gets set, and then added to as the dictionary is deserialized for each entry. If you removed it from the constructor, you would see it has the same problem and would be null after deserialization.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM