2016-12-17 13 views
2

ExpandoObject 내의 모든 속성을 PascalCase 속성 이름으로 변환하기 위해 Newtonsoft.Json.Serialization에서 DefaultContractResolver를 확장하는 사용자 지정 계약 해결자를 작성하려고합니다.DefaultContractResolver를 확장하여 ExpandoObject 하위 속성을 PascalCase로 변환

내 계약 :

public class Fruit 
{ 
    public int Id { get; set; } 
    public ExpandoObject FruitProperties { get; set; } 
} 

나는 다음과 같은 데이터를 전달하고있다 :

{ 
    "Id": "1234", 
    "FruitProperties" : { 
     "Colour": "red", 
     "Taste": "sweet" 
    } 
} 

나는 무시 ResolvePropertyName을 시도 :

는 내가 기대하고 그 결과는 다음
{ 
    "Id": "1234", 
    "FruitProperties" : { 
     "colour": "red", 
     "Taste": "sweet 
    } 

    } 

} 

입니다 , 그리고 행운과 DefaultContractResolver에 CreateProperty 메서드. 이 모든 것은 expando 객체 내의 하위 속성을 건너 뜁니다. 누구도 PascalCase에 Expando의 하위 속성 이름을 변환하기 위해 재정의해야하는 DefaultContractResolver의 메소드를 알고 있습니까?

답변

1

ExpandoObject은 반사를 통해 직렬화되지 않으므로 CreateProperty을 수정하면 작동하지 않습니다. 대신, IDictionary<string, object>으로 일련 화됩니다. 따라서 Json.NET 9.0.1에 새로운 NamingStrategy 유형을 활용하면 PascalCase 에만 맞춤 이름 지정 전략을 만들고 사전 키만 사용할 수 있습니다. 그런 다음

public class PascalCaseDictionaryKeyNamingStrategy : DefaultNamingStrategy 
{ 
    public PascalCaseDictionaryKeyNamingStrategy() : base() { this.ProcessDictionaryKeys = true; } 

    public override string GetDictionaryKey(string key) 
    { 
     if (ProcessDictionaryKeys && !string.IsNullOrEmpty(key)) 
     { 
      if (char.ToUpperInvariant(key[0]) != key[0]) 
      { 
       var builder = new StringBuilder(key); 
       builder[0] = char.ToUpperInvariant(key[0]); 
       return builder.ToString(); 
      } 
     } 
     return key; 
    } 
} 

DefaultContractResolver.NamingStrategy에 설정 (또는 custom subclass of DefaultContractResolver에 원하는 경우) :

var resolver = new DefaultContractResolver { NamingStrategy = new PascalCaseDictionaryKeyNamingStrategy() }; 
var json = JsonConvert.SerializeObject(fruit, Formatting.Indented, new JsonSerializerSettings { ContractResolver = resolver }); 

Console.WriteLine(json); 
NamingStrategytrue로 설정하면, Json.NET 사전 키 이름을 매핑하도록하는 특성 NamingStrategy.ProcessDictionaryKeys있다

출력 :

{ 
    "Id": 1234, 
    "FruitProperties": { 
    "Colour": "red", 
    "Taste": "sweet" 
    } 
}