将DefaultContractresolver扩展到将ExpandOobject子属性转换为Pascalcase



我正在尝试编写一个自定义合同解析器,该解析器在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"
  }
}

相关内容

  • 没有找到相关文章

最新更新