12

I am trying to deserialize JSON. My root object has a single property "en.pickthall". I am using dynamic type for reading my JSON. I thought I could just do away with "." in the property since its a local JSON file but then there must be some way to access such a property

var result = App_Code.FileIOHelper.ReadFromDefaultFile("ms-appx:///Assets/en.pickthall.json");

dynamic stuff = JsonConvert.DeserializeObject(result);

foreach(var x in stuff.(en.pickthall)) //Tried this intellisense didn't like it
{

}
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Rahul Jha
  • 1,131
  • 1
  • 10
  • 25

5 Answers5

23

You could create a root class to deserialize into and use JsonProperty

public class Root
{
    // Use the proper type instead of object
    [JsonProperty(PropertyName = "en.pickthall")]
    public IEnumerable<object> EnPickthall { get; set; } 

    public Root() { }
}

Used as follows

Root stuff = JsonConvert.DeserializeObject<Root>(result);

foreach(var x in stuff.EnPickthall)
{

}
Arthur Rey
  • 2,990
  • 3
  • 19
  • 42
8

You could serialize not to dynamic but to JObject and then access your property via

JObject stuff = JsonConvert.DeserializeObject<JObject>(Jsonstring);
var x = stuff.Value<String>("my.property")
derpirscher
  • 14,418
  • 3
  • 18
  • 35
  • For whatever reason, I couldn't get this code to work with Json.NET 12.0.1, I had to use `var x = stuff.SelectToken("my.property").Value();` – David McClelland Jan 17 '19 at 11:08
7

C# doesn't have any way of quoting identifiers. If it's not a valid identifier, your only option is reflection.

However, it's possible the object returned by your JSON deserializer changed the identifiers to make them useable in C# - you might want to enumerate all the properties to check if that is the case. A dynamic object with indexers might also be a solution (allowing e.g. stuff["en.pickthall"]).

Another alternative is to change the way the serializer maps properties. For example, Newtonsoft.Jsoft allows you to customize this using a IContractResolver. It's quite easy to replace the . for something more C#-sane in this way.

Luaan
  • 62,244
  • 7
  • 97
  • 116
2

I know you said you were using a dynamic type for your JSON deserialization, but I just wanted to point out that there is a .NET RESTful client out there that supports this with static model definitions too. For you or for anyone else who happens upon this response when searching for an answer to their problems with dots in property names in C# REST calls.

As of the newly released RestSharp 106.1.0 (and I do mean this version because this support was just added), it can handle renaming properties with a dot in their name via the DeserializeAs attribute. An example being when I call the ElasticSearch API for a _cat call with the following model:

public class CatResponse
{
    public string index { get; set; }
    ...
    [DeserializeAs(Name = "docs.count")]
    public string docscount { get; set; }
}

And actually get back the docs.count property deserialized into docscount now:

 var resource = $"_cat/indices/{indexPattern}?format=json&pretty=true";

 var request = new RestRequest(resource, Method.GET);
 var response = client.Execute<List<CatResponse>>(request);

This support is out of the box and doesn't need to use the Newtonsoft.Json.JsonSerializer which I have also heard is a possible solution to this problem but which I couldn't get to work.

James Eby
  • 1,784
  • 20
  • 25
0

With a dynamic object and NewtonSoft.Json:

dynamic json = JValue.Parse(result);

   int Opens = Convert.ToInt32(json.opens);

   int Clicks = Convert.ToInt32(json.clicks);

   string State = json.state;
jcat
  • 25
  • 4