2016-11-18 127 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

相關問題