0

Since I'm having a hard time explain my question, I made a fiddle. https://dotnetfiddle.net/aa18qT

I have a class that contains a list of another class with only two properties a key and a value. Alternatively I could use a dictionary. I am serializing this to json.

Currently I have

{
  "part":1,
  "quant":2,
  "comments":"something",
  "CustomFields": [
  {
    "key":"groc1",
    "value":"truffles"
  },
  {
    "key":"groc 2",
    "value":"some thing"
  }
 ]
}

And what I want is

{
   "part":1,
   "quant":2,
   "comments":"something",
   "groc 1": "truffles", 
   "groc 2":"some thing"
}

Where groc 1 and groc 2 are two of the key value pairs. The names (groc 1) are not known at compile time and could be anything in any amount. They need to be passed as parameters to another external system with those unknown fields as the name/key.

Trying to figure out how best to do this. I've been fiddling with contract resolvers and converters but not getting anywhere..maybe something with expando objects and reflection? But seems like someone must have run into this before so maybe there is an easier way all my googling hasn't found yet. Seems like it should be simple but I've been staring at it too long. I can change the structure or type of the child object, but output needs to be like above.

Any suggestions?

Marz
  • 75
  • 1
  • 8
  • 1
    "What you want" isn't JSON, it's a mixture of name/value pairs and strings. Of your "JSON" was properly formatted, this would be apparent (sorry I'd edit it, but it's beyond my phone editing skills) – Flydog57 Sep 02 '22 at 01:16
  • Might you please [edit] your question to include your code in the question itself (ideally as a [mcve]), as well as in an external link? From [ask]: *Help others reproduce the problem... if your problem is with code you've written, you should include some...Include just enough code to allow others to reproduce the problem... If it is possible to create a live example of the problem that you can link to ... then do so - but also **copy the code into the question itself**. Not everyone can access external sites, and the links may break over time.* – dbc Sep 02 '22 at 01:32
  • 1
    Anyway, you could replace `public List CustomFields { get; set; }` with `[JsonExtensionData] public Dictionary CustomFields { get; set; }` and the dictionary will be serialized as part of your model. See [this answer](https://stackoverflow.com/a/23786127) by Brian Rogers to [How to serialize a Dictionary as part of its parent object using Json.Net](https://stackoverflow.com/q/14893614) for details. In fact I think this is a duplicate, agree? – dbc Sep 02 '22 at 01:34
  • Edited. It has been a very long week. – Marz Sep 02 '22 at 01:40
  • Did you notice how obvious your problem was once I edited your JSON to make it readable. Find yourself a JSON formatting tool and keep it handy to check what you are doing – Flydog57 Sep 02 '22 at 01:43
  • I noticed how my json was messed up, it didn't help with the answer. But dbc did. – Marz Sep 02 '22 at 01:49

1 Answers1

1

you can try this

var newObj=JObject.Parse(json);
var customFields=(JArray) newObj["CustomFields"];
newObj.Properties().Where(p=> p.Name=="CustomFields").First().Remove();

foreach (JObject item in customFields)
    newObj.Add((string) item["key"],item["value"]);

json=newObj.ToString();

json

{
  "part": 1,
  "quant": 2,
  "comments": "something",
  "groc 1": "truffles",
  "groc 2": "some thing"
}

but if you need c# classes, you have to create a custom class using a Dictionary as JsonExtensionData

Item newItem=newObj.ToObject<Item>();

public class Item
{
    public int part { get; set; }
    public int quant { get; set; }
    public string comments { get; set; }

    [JsonExtensionData]
    public IDictionary<string, object> CustomFields { get; set; }
}
Serge
  • 40,935
  • 4
  • 18
  • 45
  • I think JsonExtensionData from you and dbc is going to be it. Works in my fiddle. Going to see if I can make it work in the full code. – Marz Sep 02 '22 at 01:50