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

3

你好,我想对一个类进行反序列化,而这个类中包含一个枚举值:

[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);
    }
}

字典将被正确反序列化,但枚举类型始终获取默认值。请验证JSON是否如下所示:{"Header":{"Test":"Test"},"MessageType":"Disconnect"}。我真的不明白为什么会发生这种情况,请帮忙解答,谢谢!
1个回答

4
由于在 MessageType 属性上使用了 private set,所以它不能像您想的那样工作。因此,getter 是公共的,所以可以正常序列化,但是在反序列化时被忽略了。有几种可能的解决方案:
  1. 为 MessageType 使用 public setter。但是,您最初想要使用 private setter 的原因可能并不适用。
  2. 将 JsonProperty 属性应用于 MessageType 属性:
[JsonProperty]
public MessageType MessageType { get; private set; }

将构造函数参数名称更改为 messageType 而不是 type,以便与序列化名称匹配:
public SocketMessage(MessageType messageType)
{
     Header = new Dictionary<String, String>();
     MessageType = messageType;
}

为什么对于 Header 来说这不是问题呢?因为它在构造函数中新建了一个实例。在反序列化过程中,会调用构造函数,从而设置该实例,并在每个条目反序列化时将其添加到字典中。如果你将它从构造函数中移除,你会发现它会出现相同的问题,在反序列化后仍然为 null

谢谢,它起作用了!看起来JsonProperty属性并不是问题所在,而是名称类型=> messageType解决了它,我应该继续使用属性吗?我对Json.net和json一般都很陌生。 - Traijan
1
@Traijan,这三个方法中的任何一个都可以解决问题。如果您已更改构造函数,则无需使用JsonProperty,尽管还有许多其他用途可供选择,详见此处 - steve16351

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接