c# - JsonConvert DeserializeObject 区分大小写

标签 c# json serialization deserialization case-sensitive

<分区>

我正在尝试将字符串内容反序列化为对象,但我希望内容区分大小写。只有当字符串具有小写属性时,代码才应该成功,而如果它具有大写属性,则代码应该失败。以下是类(class):

internal class ResponseList
{
    [DataMember]
    [JsonProperty]
    internal List<Response> Value { get; set; }
}

internal class Response
{
    [DataMember]
    [JsonProperty]
    internal string Id { get; set; }

    [DataMember]
    [JsonProperty]
    internal string Location { get; set; }

    [DataMember]
    [JsonProperty]
    internal PlanClass Plan { get; set; }
}

internal class PlanClass
{
    [DataMember]
    [JsonProperty]
    internal string Name { get; set; }

    [DataMember]
    [JsonProperty]
    internal string Product { get; set; }

    [DataMember]
    [JsonProperty]
    internal string Publisher { get; set; }
}

以下是我的代码。但这不区分大小写。大写和小写都成功:

string content = File.ReadAllText(contentFilePath);
JsonSerializerSettings jsonSerializerSettings1 = new JsonSerializerSettings()
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};
ResponseList response = (ResponseList)JsonConvert.DeserializeObject(contentResourceOutput, typeof(ResponseList), Constants.JsonSerializerSettings);

代码应该只有在内容是:

{
  "value": [
    {
      "id": "id1",
      "location": "location1",
      "plan": {
        "name": "free",
        "product": "product1",
        "publisher": "publisher1"
      }
    }
    ]
}

即使其中一个键是大写也会失败。例如。

{
  "value": [
    {
      "Id": "id1",
      "Location": "location1",
      "plan": {
        "Name": "free",
        "product": "product1",
        "publisher": "publisher1"
      }
    }
    ]
}

请注意,只有键/属性名称应该是小写的。值可以是大写。 有没有办法让 JsonConvert.Deserializeobject 区分大小写?

最佳答案

您可以编写自定义转换器来处理此用例。关于您需要对所有键名进行递归检查,我使用了 Thymine 给出的出色的 WalkNode 答案。 here .

var json = @"{""id"": ""id1"",""name"": ""name1"",""type"": ""type1""}";
var json2 = @"{""id"": ""id1"",""Name"": ""name1"",""type"": ""type1""}";

JsonSerializerSettings settings = new JsonSerializerSettings()
{
    ContractResolver = new CamelCasePropertyNamesContractResolver(),
    Converters = new List<JsonConverter> { new CamelCaseOnlyConverter() }
};

var response = JsonConvert.DeserializeObject<Response>(json, settings);
var response2 = JsonConvert.DeserializeObject<Response>(json2, settings);

public class CamelCaseOnlyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, 
        object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;

        var token = (JObject)JToken.Load(reader);

        var isCamelCased = true;
        WalkNode(token, null,
        t =>
        {
            var nameFirstChar = t.Name[0].ToString();
            if (!nameFirstChar.Equals(nameFirstChar.ToLower(), 
                StringComparison.CurrentCulture))
            {
                isCamelCased = false;
                return;
            }
        });

        if (!isCamelCased) return null;

        return token.ToObject(objectType);
    }

    public override void WriteJson(JsonWriter writer, object value, 
        JsonSerializer serializer)
    {
        JObject o = (JObject)JToken.FromObject(value);
        o.WriteTo(writer);
    }

    private static void WalkNode(JToken node,
                            Action<JObject> objectAction = null,
                            Action<JProperty> propertyAction = null)
    { 
        if (node.Type == JTokenType.Object)
        {
            if (objectAction != null) objectAction((JObject)node);
            foreach (JProperty child in node.Children<JProperty>())
            {
                if (propertyAction != null) propertyAction(child);
                WalkNode(child.Value, objectAction, propertyAction);
            }
        }
        else if (node.Type == JTokenType.Array)
            foreach (JToken child in node.Children())
                WalkNode(child, objectAction, propertyAction);
    }
}

第一个字符串将返回一个水合对象。第二个字符串将提前终止,返回 null。

关于c# - JsonConvert DeserializeObject 区分大小写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38754635/

相关文章:

php - R 中 var_dump() 的等价物是什么?

对象属性的 C# Web 服务序列化

java - Java中序列化的目的是什么?

c# - EF 中的映射实体出错

c# - 可编程命名变量?

c# - 如何在网格中移动项目

c# 如何将阿拉伯字符编码为utf8?

javascript - 将 Big GeoJSON 转换为 topoJSON

xml - XSLT + 用转义序列替换双引号

java - 使用gson反序列化json