2016-11-18 43 views
0

我正在使用Json.NET(8.0.3),并试图将CamelCasePropertyNameContractResolver与JsonConvert.DeseralizeObject()一起使用,以便我可以读取具有驼峰大小写属性的JSON。这是JSON的一个例子。Json.NET CamelCasePropertyNameContractResolver不与私有属性设置器一起使用

{ "name":"somename", "type":"sometype" } 

这里是我尝试反序列化到类:

public class MyClass { 
    public string Name { get; private set; } 
    public string Type { get; private set; } 
} 

如果我使用JsonConvert.DeseralizeObject的名称和类型的值是零,因为技术上的类属性名的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; } 
} 

这里的答案显然是只保留二传手公开的,但是如果我想/需要有二传手私人的,我怎么能得到CamelCasePropertyNameContractResolver与私人制定者的工作?我做错了什么,或者这是一个可能的错误?

回答

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.是不正确的。如果你的财产是公共getter和setter方法,反序列化使用默认设置时,会忽略的情况下(这是我在这个答案中使用我的ContractResolver还包括在反序列化过程中的私人性质;这是所有).....

见我用同样的ContractResolver其他问题:What am I doing wrong with JSON.NET's JsonConvert

+0

@LB感谢您的答复快和澄清deseralization私人setter方法是如何工作的。因此,我的选择是在每个属性上使用JsonProperty和私人setter,或者使用像您发布的那样的定制ContractResolver,因为它包含私有setter? – Eric

相关问题