C# 扩展DefaultContractResolver以将ExpandoObject子属性转换为PascalCase

C# 扩展DefaultContractResolver以将ExpandoObject子属性转换为PascalCase,c#,asp.net-mvc,serialization,json.net,expandoobject,C#,Asp.net Mvc,Serialization,Json.net,Expandoobject,我正在尝试编写一个自定义契约解析器,它在Newtonsoft.Json.Serialization中扩展DefaultContractResolver,目标是将ExpandooObject中的所有属性转换为具有PascalCase属性名称 我的合同: public class Fruit { public int Id { get; set; } public ExpandoObject FruitProperties { get; set; } } 我正在传递以下数据: {

我正在尝试编写一个自定义契约解析器,它在Newtonsoft.Json.Serialization中扩展DefaultContractResolver,目标是将ExpandooObject中的所有属性转换为具有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中重写ResolvePropertyName和CreateProperty方法,但没有成功。所有这些都会跳过expando对象中的子属性。有人知道我需要覆盖DefaultContractResolver中的哪个方法才能将Expando中的子属性名转换为PascalCase吗?

ExpandoObject
没有通过反射序列化,因此修改不起作用。相反,它被序列化为
IDictionary
。因此,您可以利用中的新类型创建一个自定义命名策略,以便只使用字典键而不使用其他内容
NamingStrategy
有一个属性,当设置为
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;
    }
}
然后将其设置为(或任何您喜欢的设置):

哪些产出:

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

您的自定义NamingStrategy类可以从
NamingStrategy
继承,而不是从
DefaultNamingStrategy
继承,这种方法仍然有效
{
  "Id": 1234,
  "FruitProperties": {
    "Colour": "red",
    "Taste": "sweet"
  }
}