-1

consider the following json file

{
  "test": {
    "CR": {
     "name": "Car"
    },
    "BK": {
     "name": "Bike"
    }
}

How can i combine usage of anonymous types with LINQ to JSON for creating key-value pairs of

    CR Car
    BK Bike

by using LINQ to JSON?

I have tried something as simple as the following for start, but it does not even compile

    JObject o = JObject.Parse(s);
    var pairs = o["test"].Select(x => x.Value).ToList();

To be more precise something like this pseudocode

var pairs = o["test"].Select( new { key = x => x.firstOrDefault().Name, value = x => x.Value}).ToList();
dbc
  • 104,963
  • 20
  • 228
  • 340
OrElse
  • 9,709
  • 39
  • 140
  • 253
  • You should access `test` properties by name or cast to `JProperty` – Pavel Anikhouski Jul 06 '20 at 19:33
  • 1
    @OlivierRogier I don't see how showing how to work with JSON can answer this "create anonymous types at runtime" question... Unless OP clarifies what they *actualy* want to achieve. – Alexei Levenkov Jul 06 '20 at 19:34
  • @OrElse are you familiar with lambda expressions? I suggest you to look at basics of it first and make your code compile – Pavel Anikhouski Jul 06 '20 at 19:44
  • @OlivierRogier May i ask why you closed the question? – OrElse Jul 06 '20 at 19:47
  • @OrElseq because it looks like one of the suggested duplicates is what you are asking. Indeed you are welcome to [edit] question to clarify why neither apply to your case. – Alexei Levenkov Jul 06 '20 at 19:50
  • 1
    You can always just use LINQ to JSON to create a new `JObject` based on the original one, i.e. `var pairs = new JObject( ((JObject)o["test"]).Properties().Select(p => new JProperty(p.Name, p.Value["name"])) );`. Or if you would prefer a dictionary then `var dictionary = ((JObject)o["test"]).Properties().ToDictionary(p => p.Name, p => (string)p.Value["name"]);`. See: https://dotnetfiddle.net/5fnn5E – dbc Jul 06 '20 at 20:35
  • If you **must** have a runtime-created anonymous type, see [C# anonymous object with properties from dictionary](https://stackoverflow.com/a/29428640/3744182). It's nontrivial though. – dbc Jul 06 '20 at 20:41
  • @dbc do you mind posting this as an answer? This is what i was looking for – OrElse Jul 06 '20 at 21:09

1 Answers1

1

Rather than creating a runtime anonymous type with variable property names, you could use LINQ to JSON to create a restructured JObject like so:

var pairs = new JObject( ((JObject)o["test"])
                        .Properties()
                        .Select(p => new JProperty(p.Name, p.Value["name"])) );

Or, if you would prefer a Dictionary<string, string>, you may do:

var dictionary = ((JObject)o["test"]).Properties()
    .ToDictionary(p => p.Name, p => (string)p.Value["name"]);

Or an ExpandoObject:

var expando = new ExpandoObject();
foreach (var p in ((JObject)o["test"]).Properties())
{
    IDictionary<string, object> d = expando;
    d.Add(p.Name, (string)p.Value["name"]);
}

Creating a run-time anonymous type using property names defined by a dictionary is nontrivial as it requires runtime code generation. If you really need this, see C# anonymous object with properties from dictionary.

Demo fiddle here.

dbc
  • 104,963
  • 20
  • 228
  • 340