在将JSON解析为JToken时如何将所有键更改为小写

时间:2016-11-29 07:13:44

标签: c# json json.net jsonschema json-deserialization

我有一个JSON字符串,键有大写和小写字符:

{"employees":[
    {"FIrstName":"John", "LASTname":"Doe"},
    {"FIRSTNAME":"Anna", "LaSTNaME":"Smith"},
    {"firstName":"Peter", "lastName":"Jones"}
]}

我希望将其转换为JToken对象,并使JToken中的所有键都为小写。因此JToken内部应该如下:

{"employees":[
    {"firstname":"John", "lastname":"Doe"},
    {"firstname":"Anna", "lastname":"Smith"},
    {"firstname":"Peter", "lastname":"Jones"} 
]}

以前我使用JToken json = JToken.Parse(jsonString);进行转换,但我无法找到如何将密钥设为小写。 有什么想法吗?

我需要这样做的原因是我的JsonSchema验证不区分大小写。

1 个答案:

答案 0 :(得分:5)

使用最少代码解决此问题的一种可能方法是继承JsonTextReader并覆盖Value属性,以便在当前TokenTypePropertyName时返回小写字符串:

public class LowerCasePropertyNameJsonReader : JsonTextReader
{
    public LowerCasePropertyNameJsonReader(TextReader textReader)
        : base(textReader)
    {
    }

    public override object Value
    {
        get
        {
            if (TokenType == JsonToken.PropertyName)
                return ((string)base.Value).ToLower();

            return base.Value;
        }
    }
}

这是有效的,因为基础JsonTextReader使TokenType更新为内部状态更改,并且序列化程序(实际上是JsonSerializerInternalReader类)依赖于它来检索属性通过Value属性从读者那里输入名称。

您可以创建一个简短的帮助方法,以便使用自定义阅读器轻松反序列化:

public static class JsonHelper
{
    public static JToken DeserializeWithLowerCasePropertyNames(string json)
    {
        using (TextReader textReader = new StringReader(json))
        using (JsonReader jsonReader = new LowerCasePropertyNameJsonReader(textReader))
        {
            JsonSerializer ser = new JsonSerializer();
            return ser.Deserialize<JToken>(jsonReader);
        }
    }
}

然后在您的代码中,只需替换它:

JToken json = JToken.Parse(jsonString);

用这个:

JToken json = JsonHelper.DeserializeWithLowerCasePropertyNames(jsonString);

小提琴:https://dotnetfiddle.net/A0S3I1