0

I am using an API that frustratingly requires you to omit optional parameters rather than pass them as null.

Also, data is slightly nested in the format:

{ data: { prop1: 5, prop2: 6, prop3: 7 } }

Previously I was converting it using a replace:

"{ data: { prop1: {prop1}, prop2: {prop2}, prop3: {prop3} } }"
   .Replace("{prop1}", prop1)....

But it turns out that if a value is not provided the API I am sending this to will only accept it if it's not included in the JSON.

Rather than mess around with complex string concatenation (as I am not using model binding), I thought about simply creating a dictionary and serialising it to JSON.

If I do this:

Dictionary<string, int> props = new Dictionary<string, int>
{
     { "prop1", 6 },
     { "prop3", 7 },
};

string json = JsonConvert.SerializeObject(props, Formatting.Indented);

I can serialise whichever props I need nicely. Unfortunately you can see the way I need to send the data is contained within the data property of the json. I would need to put a dictionary inside my dictionary, but the dictionary is defined as string, int so that isn't possible. If I changed the type, then I'd not be able to put my props in.

To solve this I can see 2 possible clean ways:

  • Dynamically compose a JSON object somehow sorta like XML

eg. new JsonObject().AddNode("data").AddProperty("Prop1", 3).AddProperty("Prop3", 5).... etc.

  • Serialise from a dictionary object in a way that will let me include the nested property. Or, find a way to assign the json from a non-nested dictionary into the data property of a new json object.

I've not found a way to do this cleanly yet - alternatively another suggestion on solving this issue would be appreciated.

NibblyPig
  • 51,118
  • 72
  • 200
  • 356
  • 3
    Possible duplicate of [How to ignore a property in class if null, using json.net](http://stackoverflow.com/questions/6507889/how-to-ignore-a-property-in-class-if-null-using-json-net) – Fran Jan 31 '17 at 16:10
  • The duplicate example is using model binding whereas I am not. – NibblyPig Feb 01 '17 at 08:42

1 Answers1

1

Not sure what your problem is with the dictionary approach. This works fine:

var props = new Dictionary<string, Dictionary<string, int>>
            {
                { "data", new Dictionary<string, int>
                          {
                              {"prop1", 6},
                              {"prop3", 7}
                          }
                }
            };

var json = JsonConvert.SerializeObject(props, Formatting.Indented);
Michael Gunter
  • 12,528
  • 1
  • 24
  • 58
  • Ah interesting, that will work but only for this instance I think. The reason I didn't think it'd work before was because it only works in that specific instance - how would you add a property at the same tier of data such as `id: 123` ? As it wants a dictionary as the value. If there's a way to solve it for this situation it will help me down the line when invariably I come across a scenario that requires me to put a kvp at the top level alongside data. – NibblyPig Feb 01 '17 at 08:45
  • You would add `id:123` same as you add `data:{...}`. Just add an `id` entry to the root dictionary. – Michael Gunter Feb 02 '17 at 16:28