我正在使用Json.NET(8.0.3),我正在尝试将CamelCasePropertyNameContractResolver与JsonConvert.DeseralizeObject()一起使用,以便我可以使用驼峰大小写属性读取JSON。这是JSON的一个例子。
{ "name":"somename", "type":"sometype" }
以下是我尝试反序列化的课程:
public class MyClass {
public string Name { get; private set; }
public string Type { get; private set; }
}
如果我使用JsonConvert.DeseralizeObject,则Name和Type值为null,因为从技术上讲,类属性名称与JSON属性名称不匹配。这是预料之中的。如果我添加JsonProperty属性,那么它将正确反序列化(也是预期的)。
public class MyClass {
[JsonProperty("name")]
public string Name { get; private set; }
[JsonProperty("type")]
public string Type { get; private set; }
}
我不想将JsonProperty属性放在所有属性上,所以我尝试了CamelCasePropertyNameContractResolver。
JsonConvert.DefaultSettings = () => new JsonSerialierSettings {
ContractResolver = new CamelCasePropertyNameContractResolver()
};
MyClass value = JsonConvert.DeserializeObject<MyClass>(json);
MyClass对象的Name和Type属性都是null,这是意外的。如果我公开setter那么它可以正常工作。
public class MyClass {
public string Name { get; set; }
public string Type { get; set; }
}
这里显而易见的答案是只保持setter公开,但如果我想/需要将setter设为私有,那么如何让CamelCasePropertyNameContractResolver与私有setter一起工作?我做错了什么,或者这是一个可能的错误?
答案 0 :(得分:3)
您可以通过撰写自定义ContractResolver
string json = @"{""name"":""somename"", ""type"":""sometype"" }";
var settings = new JsonSerializerSettings() {
ContractResolver = new AllPropertiesContractResolver() };
var res = JsonConvert.DeserializeObject<MyClass>(json,settings);
public class MyClass
{
public string Name { get; private set; }
public string Type { get; private set; }
}
public class AllPropertiesContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var props = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
.Select(x => new Newtonsoft.Json.Serialization.JsonProperty()
{
PropertyName = x.Name,
PropertyType = x.PropertyType,
Readable = true,
ValueProvider = new AllPropertiesValueProvider(x),
Writable = true
})
.ToList();
return props;
}
}
public class AllPropertiesValueProvider : Newtonsoft.Json.Serialization.IValueProvider
{
PropertyInfo _propertyInfo;
public AllPropertiesValueProvider(PropertyInfo p)
{
_propertyInfo = p;
}
public object GetValue(object target)
{
return _propertyInfo.GetValue(target); //Serialization
}
public void SetValue(object target, object value)
{
_propertyInfo.SetValue(target, value, null); //Deserialization
}
}
BTW:If I use JsonConvert.DeseralizeObject the Name and Type values are null because technically the class property names do not match the JSON property names.
不正确。如果您的属性具有公共setter和getter,反序列化将忽略使用默认设置时的情况(这是我在此答案中使用的。我的ContractResolver还包括反序列化过程中的私有属性;这就是全部).....
请参阅我使用相同ContractResolver的其他问题:What am I doing wrong with JSON.NET's JsonConvert