JSON.NET将实现IDictionary <tkey,tvalue =“”>的对象反序列化为字典,如何强制进行常规类序列化?

时间:2016-11-18 11:21:31

标签: c# json dictionary serialization json.net

假设我已经定义了interface

public interface IExtensibleObject : IDictionary<string, object>
{
    // Some members here, but it doesn't matter for this question
}

我设计了一个实现整个界面的类:

public class Customer : IExtensibleObject
{
     public Guid Id { get; set; }

     // IExtensibleObject implemented members
}

当我尝试将JSON string反序列化为Customer时,JSON.NET将访问IDictionary<TKey, TValue>索引器以设置Id属性(即instance["Id"] = value) :

Customer customer = JsonConvert.DeserializeObject<Customer>(@"{""Id"":""bcf66a92-00ea-4124-afa7-a6c200ae5886""}");

是否有一些内在的方法可以避免整个行为?。我需要将整个对象反序列化为常规对象,即使它实现了IDictionary<TKey, TValue>

2 个答案:

答案 0 :(得分:3)

您可以使用自定义合约解析程序执行此操作。默认合同解析程序检查类是否实现IDictionary,如果是,则序列化\反序列化它。你可以改变:

class CustomResolver : DefaultContractResolver {
    protected override JsonContract CreateContract(Type objectType) {
        // if type implements your interface - serialize it as object
        if (typeof(IExtensibleObject).IsAssignableFrom(objectType)) {
            return base.CreateObjectContract(objectType);
        }

        return base.CreateContract(objectType);
    }
}

然后只是:

 var settings = new JsonSerializerSettings(); // or change default settings
 settings.ContractResolver = new CustomResolver();                        
 Customer customer = JsonConvert.DeserializeObject<Customer>(@"{""Id"":""bcf66a92-00ea-4124-afa7-a6c200ae5886""}", settings);

答案 1 :(得分:1)

您可以在此处找到答案:Duplicate Question

我知道的唯一方法与链接中的答案相同 - 您必须实现自定义JsonConverter

public class CustomerConverter : JsonConverter 
{
     public override bool CanConvert(Type objectType)
     {
        return objectType == typeof (Customer);
     }
     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
      {
            var eobj = (Customer) value;
            var temp = new Dictionary<string, object>(eobj);
            temp.Add("Id", eobj.Id);
            serializer.Serialize(writer, temp);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
            JsonSerializer serializer)
        {
            var temp = serializer.Deserialize<Dictionary<string, object>>(reader);
            var eobj = new Customer();
            foreach (var key in temp.Keys)
            {
                if (key == "Id")
                    eobj.Id = (Guid) temp[key];
                else
                    eobj.Add(key, temp[key]);
            }
            return eobj;
        }
    }