简体   繁体   中英

How to throw an exception when member comes twice on Deserializing with JsonConvert

I have JSON which contains duplicated members:

[
  {
    "MyProperty": "MyProperty1",
    "MyProperty": "MyWrongProperty1",
    "MyProperty2": "MyProperty12",
    "MyProperty2": "MyWrongProperty2"
  },
  {
    "MyProperty": "MyProperty21",
    "MyProperty2": "MyProperty22"
  }
]

When I deserialize, it is getting the last property. Here is the code:

var myJson = File.ReadAllText("1.txt");
List<MyClass> myClasses = JsonConvert.DeserializeObject<List<MyClass>>(myJson);

But I need to throw an exception when JSON string contains duplicated properties. How can I do that?

You can use JsonTextReader from Newtonsoft.Json to get all tokens which are of PropertyName and then probably use LINQ GroupBy() like

string json = "[
  {
    "MyProperty": "MyProperty1",
    "MyProperty": "MyWrongProperty1",
    "MyProperty2": "MyProperty12",
    "MyProperty2": "MyWrongProperty2"
  },
  {
    "MyProperty": "MyProperty21",
    "MyProperty2": "MyProperty22"
  }
]";

List<string> props = new List<string>();

JsonTextReader reader = new JsonTextReader(new StringReader(json));
while (reader.Read())
{
    if (reader.Value != null && reader.TokenType == "PropertyName")
    {
        props.Add(reader.Value);
    }
}

Now use GroupBy() on the list to see duplicates

var data = props.GroupBy(x => x).Select(x => new 
           {
             PropName = x.Key,
             Occurence = x.Count()
           }).Where(y => y.Occurence > 1).ToList();

If (data.Any())
{
  Throw New Exception("Duplicate Property Found");
}

You need to added DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error in your JsonLoadSettings .

You can dig in details following this answer .

There is also a thread from Newtonsoft.json that cover this topic.

Here you go:

            public object DeserializeObject(string json)
            {
                using (var stringReader = new StringReader(json))
                using (var jsonReader = new JsonTextReader(stringReader))
                {

                    return JToken.ReadFrom(jsonReader, 
                        new JsonLoadSettings{ DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error })
                        .ToObject<object>();
                }
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM