我正在尝试编写一个自定义合同解析器,该解析器在newtonsoft.json.serialization中扩展了DefaultContractresolver,其目的是将ExpandOobject中的所有属性转换为具有Pascalcase属性名称。
我的合同:
public class Fruit
{
public int Id { get; set; }
public ExpandoObject FruitProperties { get; set; }
}
我正在传递以下数据:
{
"Id": "1234",
"FruitProperties" : {
"colour": "red",
"Taste": "sweet
}
}
}
我期望的结果如下:
{
"Id": "1234",
"FruitProperties" : {
"Colour": "red",
"Taste": "sweet"
}
}
我已经尝试了defaultContractresolver中的Resolve resolve resolve propertyname和createProperty方法,没有运气。所有这些都跳过了Expando对象中的子属性。有谁知道我需要覆盖的默认方法中的哪种方法将Expliono中的子属性名称转换为Pascalcase?
ExpandoObject
不是通过反射序列化的,因此修改CreateProperty
无法正常工作。相反,它被序列化为IDictionary<string, object>
。因此,您可以利用JSON.NET 9.0.1中的新的NamingStrategy
类型来创建一个自定义命名策略,以唯一的字典键,而别无其他。NamingStrategy
具有属性NamingStrategy.ProcessDictionaryKeys
,该属性将设置为 true
时,会导致json.net映射字典密钥名称:
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
上(如果愿意,请在DefaultContractResolver
的任何自定义子类上):
var resolver = new DefaultContractResolver { NamingStrategy = new PascalCaseDictionaryKeyNamingStrategy() };
var json = JsonConvert.SerializeObject(fruit, Formatting.Indented, new JsonSerializerSettings { ContractResolver = resolver });
Console.WriteLine(json);
输出:
{
"Id": 1234,
"FruitProperties": {
"Colour": "red",
"Taste": "sweet"
}
}