假设我已经定义了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>
。
答案 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;
}
}