C# Json.NET 不区分大小写的属性反序列化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11266695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 17:11:40  来源:igfitidea点击:

Json.NET Case-insensitive Property Deserialization

c#json.net

提问by Phil Klein

Json.NET lists "Case-insensitive property deserialization" as one of the advertised features. I have read that an attempt will first be made to match the case of the property specified and if a match is not found a case-insensitive search is performed. This does not appear to be the default behavior however. See the following example:

Json.NET 将“不区分大小写的属性反序列化”列为宣传的功能之一。我读到将首先尝试匹配指定属性的大小写,如果未找到匹配项,则执行不区分大小写的搜索。然而,这似乎不是默认行为。请参阅以下示例:

var result =
    JsonConvert.DeserializeObject<KeyValuePair<int, string>>(
        "{key: 123, value: \"test value\"}"
    );

// result is equal to: default(KeyValuePair<int, string>)

If the JSON string is altered to match the case of the properties ("Key" and "Value" vs "key" and "value") then all is well:

如果更改 JSON 字符串以匹配属性的大小写(“Key”和“Value”与“key”和“value”),那么一切都很好:

var result =
    JsonConvert.DeserializeObject<KeyValuePair<int, string>>(
        "{Key: 123, Value: \"test value\"}"
    );

// result is equal to: new KeyValuePair<int, string>(123, "test value")

Is there a way to perform to case-insensitive deserialization?

有没有办法执行不区分大小写的反序列化?

采纳答案by James Newton-King

That's a bug.

那是一个错误。

Case-insensitive property deserialization refers to Json.NET being able to map a JSON property with the name "Key" to either a .NET class's "Key" or "key" member.

不区分大小写的属性反序列化是指 Json.NET 能够将名为“Key”的 JSON 属性映射到 .NET 类的“Key”或“key”成员。

The bug is KeyValuePair requires its own JsonConverter but misses out of the case insensitive mapping.

错误是 KeyValuePair 需要它自己的 JsonConverter 但错过了不区分大小写的映射。

https://github.com/JamesNK/Newtonsoft.Json/blob/fe200fbaeb5bad3852812db1e964473e1f881d93/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs

https://github.com/JamesNK/Newtonsoft.Json/blob/fe200fbaeb5bad3852812db1e964473e1f881d93/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs

Use that as a base and add the lower case "key" and "value" to the case statement when reading JSON.

使用它作为基础,并在读取 JSON 时将小写的“键”和“值”添加到 case 语句中。

回答by Hemanshu Shah

One efficient way I found was to use GetValue with StringComparer parameter.

我发现的一种有效方法是将 GetValue 与 StringComparer 参数一起使用。

So for example,

例如,

JObject contact;
String strName = contact.GetValue('Name');

You are trying to access 'Name' property as case insensitive, you can use

您正在尝试以不区分大小写的方式访问“名称”属性,您可以使用

JObject contact;
String strName = contact.GetValue("ObjType", StringComparison.InvariantCultureIgnoreCase);

回答by martin hui

You can use a custom Contract resolver on incoming property name, which you can change the incoming property into a preferable format that will matches your C# object class property format. I have made three custom contract resolver, that will change the incoming property name into Title case / Lower case / upper case:

您可以对传入属性名称使用自定义合同解析器,您可以将传入属性更改为与 C# 对象类属性格式匹配的首选格式。我制作了三个自定义合同解析器,它将传入的属性名称更改为标题大小写/小写/大写:

public class TitleCaseContractResolver : DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName)
    {
        //Change the incoming property name into Title case
        var name = string.Concat(propertyName[0].ToString().ToUpper(), propertyName.Substring(1).ToLower());
        return base.ResolvePropertyName(name);
    }
}

public class LowerCaseContractResolver : DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName)
    {
        //Change the incoming property name into Lower case
        return base.ResolvePropertyName(propertyName.ToLower());
    }
}

public class UpperCaseContractResolver : DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName)
    {
        //Change the incoming property name into Upper case
        return base.ResolvePropertyName(propertyName.ToUpper());
    }
}

Then create a new JsonSerializerSetting object and put your custom contract resolver into the property ContractResolver. Then add the JsonSerializerSetting object into the second parameter in the JsonConvert.DeserializeObject(jsonString, jsonSerializerSetting)

然后创建一个新的 JsonSerializerSetting 对象并将您的自定义合同解析器放入属性 ContractResolver 中。然后将 JsonSerializerSetting 对象添加到 JsonConvert.DeserializeObject(jsonString, jsonSerializerSetting) 中的第二个参数中

        var serializerSetting = new JsonSerializerSettings()
        {
            ContractResolver = new TitleCaseContractResolver()
        };
        var result = JsonConvert.DeserializeObject<YourType>(jsonString, serializerSetting);