简体   繁体   English

使用 Newtonsoft.Json 进行枚举反序列化

[英]Enum deserialization with Newtonsoft.Json

Hello I want to deserialize a class and in this class is a enum value:您好我想反序列化一个 class 并且在这个 class 中是一个枚举值:

[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"}字典将被正确反序列化,但枚举总是得到他的默认值 >verify< json 看起来像这样: {"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.由于MessageType属性上的private set ,它无法正常工作。 So the getter is public and so it serializes fine, but when it comes to deserialize, it is ignored.所以getter是公共的,所以它可以很好地序列化,但是在反序列化时,它被忽略了。 There are a few possible solutions to this.有几个可能的解决方案。

  1. Use a public setter for MessageType .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属性应用于MessageType属性:
[JsonProperty]
public MessageType MessageType { get; private set; }
  1. Change the constructor parameter name to messageType instead of type , so it matches the serialized name:将构造函数参数名称更改为messageType而不是type ,使其与序列化名称匹配:
public SocketMessage(MessageType messageType)
{
     Header = new Dictionary<String, String>();
     MessageType = messageType;
}

Why was it not a problem for Header ?为什么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.如果你从构造函数中删除它,你会看到它有同样的问题,反序列化后会是null

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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