0

I would like to skip some dictionary value that same as a default value.

Here is the simplified code of that dictionary

public Dictionary<int, Item> allItems;

public class Item
{
    public bool IsSelected;
    public List<string> SelectionInfo;
}

So, as of right now, my JSON output looks like this:

"allItems": {
    "0": {
      "IsSelected": true,
      "SelectionInfo": [
        "yes",
        "maybe",
        "no"
      ]
    },
    "1": {
      "IsSelected": false,
      "SelectionInfo": []
    }
  }

I want to skip the "1" But don't just entirely skip it, at least keep the key so it can be restored at later. and have 0 and 1 on the dictionary

Like this?

"allItems": {
    "0": {
      "IsSelected": true,
      "SelectionInfo": [
        "yes",
        "maybe",
        "no"
      ]
    },
    "1": { }
  }

I was looking around and found out that you can use JsonConverter. But my case JSON tool is on the other Project (Utility.Please.TurnToJson(item);) and I want to keep it consistent and use only one JSON across all projects. Maybe if JsonConverter is the only option, at least provide me the solution on how to pass the custom JsonConverter to that project.

///somewhat like this?
Utility.Please.TurnToJson(item, new List<object>(){
    typeof(Custom1),
    typeof(Custom2)
});
ToonWK
  • 47
  • 1
  • 8
  • 2
    So how's your expected output look? – er-sho Jan 30 '19 at 11:52
  • @er-mfahhgk I updated the wanted result. – ToonWK Jan 30 '19 at 12:07
  • So how we decide that only keep its key? it on the basis of `SelectionInfo` array is empty or `IsSelected` is false? – er-sho Jan 30 '19 at 12:12
  • @er-mfahhgk both. If the IsSelected is false and the list is empty! – ToonWK Jan 30 '19 at 12:17
  • To skip serialization of `IsSelected` when the value is false, set `[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]` as shown in [Is there an alternative for `ShouldSerialize[PropertyName]` in C#?](https://stackoverflow.com/q/50795025/3744182). To skip serialization of collections when they are empty, see [Can Newtonsoft Json.NET skip serializing empty lists?](https://stackoverflow.com/q/11320968) and/or [How to make Json.Net skip serialization of empty collections](https://stackoverflow.com/q/18471864/3744182). In fact this might be a duplicate of those three. Agree? – dbc Jan 30 '19 at 12:29
  • @ToonWK, I added my answer below, try it and let me know :) – er-sho Jan 30 '19 at 12:58

1 Answers1

0

Here is the JsonConverter that can give you your expected output.

The converter can keep your key ai it is if IsSelected = false and SelectionInfo array is empty.

public class MyCustomJsonConverter : JsonConverter
{
    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JObject jObj = new JObject();
        if (value != null)
        {
            var dict = JObject.Parse(value as string)["allItems"].ToObject<Dictionary<string, Item>>();
            foreach (var item in dict)
            {
                JObject jObject = new JObject();

                if (item.Value.IsSelected == false && item.Value.SelectionInfo.Count == 0)
                {
                    jObj.Add(new JProperty(item.Key, new JObject()));
                }
                else
                {
                    jObj.Add(new JProperty(item.Key, JObject.FromObject(item.Value)));
                }
            }
        }

        JObject jMainObject = new JObject();
        jMainObject.Add(new JProperty("allItems", jObj));
        jMainObject.WriteTo(writer);
    }
}

Usage:

string json = File.ReadAllText(@"Path to your json file");

string output = JsonConvert.SerializeObject(json, new MyCustomJsonConverter());

Output:

enter image description here

er-sho
  • 9,581
  • 2
  • 13
  • 26
  • So, I just had a chance to test it today. And as soon as I put on my project the first thing I got is ArguementException at this line `var dict = JObject.Parse(value as string)["allItems"].ToObject>();` My dictionary is int, do I need to change it to int? Or keep it as string? – ToonWK Jan 31 '19 at 04:18
  • 1
    I think you keep it as a string because your json keys are in string means those are wrapped with quotes like `"1", "2"` instead of integers like `1, 2`. So json keys are string always not int, but the value for those keys are in any type means it can be int, string, boolean etc. :) – er-sho Jan 31 '19 at 05:35