Reading nested dynamic JSON attributes - c#

First of all I have checked all old questions and found this one useful: Reading dynamic attributes of json into .net C# but wasn't so useful in my case, I'm missing something not sure what is it!
I'm trying to read dynamic JSON with nested dynamic attributes, here is the JSON:
{"data":{"cart":{"seats":{"3B00535EF2414332":{"212":{"6":["22","21"]}}}}}}
Please keep in mind that 3B00535EF2414332, 212 and 6 are dynamic each time I get this JSON.
In C#, I don't know how should I set the attributes as I need to provide a class with properties with exact the same name of the object to deserialize this object. I though about parsing it to dynamic object in C# and try to call it, but still can't as the only known value for me each time is 3B00535EF2414332 but other 2 dynamic properties are not known to me, I need to retrieve them.
I though about the dictionary way, but I couldn't create it right. Actually, I didn't understand it right.
Thanks for your time.

You can try this:
var results = JObject.Parse(json)
["data"]["cart"]["seats"]
.Children<JProperty>().First().Value
.Children<JProperty>().First().Value
.Children<JProperty>().First().Value
.ToObject<int[]>();
EDIT: you can also use this to retrieve the values along with the path names:
var seats = JObject.Parse(json)["data"]["cart"]["seats"].Children<JProperty>();
var unknown0 = seats.First();
var unknown1 = unknown0.Value.Children<JProperty>().First();
var unknown2 = unknown1.Value.Children<JProperty>().First();
// unknown0.Name -> 3B00535EF2414332
// unknown1.Name -> 212
// unknown2.Name -> 6;
// unknown2.Value.ToObject<int[]>() -> [22,21]

Related

List does not get saved when I use Application.Current.SavePropertiesAsync in Xamarin forms

I am currently trying to save a list in Xamarin forms. I use this code snippet:
var list = new List<myClass> ();
Application.Current.Properties["myList"] = list;
await Application.Current.SavePropertiesAsync();
When I then close the app and use this code...
if (Application.Current.Properties.ContainsKey("myList"))
{
}
...I cannot reach this if statement.
I read something about people having issues saving a list with this solution but they solved it by converting it to a string. I am a bit unsure on how to do this. If I do this...
Application.Current.Properties["myList"] = list.ToString();
...the app crashes.
I saw that there is a plugin called "Settings" that I might need to use instead in case there isn't a solution to this problem but I would prefer to work with my current code if possible.
The Properties dictionary can only serialize primitive types for
storage. Attempting to store other types (such as List can
fail silently).
It means that you can't save List because it's not a primitive type of object. You can serialize it to JSON string for example then it will work. Code example:
var jsonValueToSave = JsonConvert.SerializeObject(myList);
Application.Current.Properties["myList"] = jsonValueToSave;
await Application.Current.SavePropertiesAsync();
Don't forget to deserialize JSON to List<string> when loading the value back.
Note that yourList.ToString() will not work in this case. More info here.
P.S.: Get familiar with the official documentation & check this post on another related thread.

Cannot deserialize type without setter

I have binary serialized objects in database. They are serialized with protobuf.
Now I need to generate some viewer to see the content of Database.
So, i read stream from database and deserialized it back to the objects.
It works and the result is list of objects:
var dbData = readData(someType);//it is IList collection
Now, I would like to save this list of objects to file to see the content of database. I thought it would be the best to save it to xml. So, i have tried:
var serializer = new XmlSerializer(dbData.GetType());
But i get an error: Cannot deserialize type 'My.Entities.IdBase' because it contains property 'Key' which has no public setter.
What now? I can't change the class definitions to have setters.
Should i save objects to json or plain text instead? Or should i extract all properties and values and save it to some xml? Any code example?
JSON.NET would be the answer here. You can find it in nuget. Use it like this:
JsonConvert.DeserializeObject<T>(input);

JSON pattern recognition

Suppose I have a JSON request body req1, and it resulted in a JSON response resp1, some of whose key-values are identical to those in req1. Now suppose I have another JSON request req2, and I want to construct a JSON response resp2 which is a duplicate of resp1, but in which the common keys have their values replaced by the values from req2.
What strategy might be used to tackle this?
As a concrete example, suppose req1 is this:
{"Name":"Alan"}
And suppose this is resp1:
{"output":{"Name":"Alan", "Cat": "12"}}
Note that "Name":"Alan" appears in both.
If req2 is this:
{"Name":"Bancorp"}
Then I'd like to create resp2 from resp1 like this:
{"output":{"Name":"Bancorp", "Cat": "12"}}
Crucially, the document structure of req* and resp* are not known in advance, and the only knowledge is that the structure of req1 and req2 are similar, and likewise for resp1 and resp2.
In other words, I'm looking for a flexible pattern-recognition that will "learn" from an initial req1/resp1 pair by identifying fields that occurred in both, and then be able to respond to future req* inputs by making the proper substitutions to a copy of resp1.
Is this something which already exists? If not, how might it be implemented in JSON.Net?
I would deserialize your requests into separate objects first. You could then use reflection to get a list of all the properties of each object and filter the results to only show the common properties.
obj.GetType().GetProperties();
Once you have your list of properties that you need in the response object, you can create a new ExpandoObject and dynamically add the properties and corresponding values that you need.
dynamic x = new ExpandoObject();
x.NewProp = string.Empty;
Once you're done, you can serialize this response object back to JSON.

NewtonSoft.Json error

Hi I'm quite new to C# and I'm trying to make a text editor that saves and loads Plaintext formats. I've used NewtonSoft.Json NuGet package, but I'm getting an error. I've stated a string called textToLoad, which is set to a JsonConvert.DeserializeObject. Only thing is, it says it can't convert an object to a string! I tried toString(); but it still had the same error.
It is kind of hard without the code. The process of serializing and deserializing is pretty straight forward using Json.Net. So this is an example from their documentation:
YourType yourObject= new YourType();
yourObject.Property="something";
string output = JsonConvert.SerializeObject(yourObject);
//For some reason you want this to be string, but is the type you serialized in the first place
YourType textToLoad= JsonConvert.DeserializeObject<YourType>(output);
This outlines the basic works of serializing and deserializing. But we don't really know the details of your implementation.
Hope it helps.
You can't deserialize into a string like that. At simplest form you started with JSON in the form of:
{ value: "someString" }
If you want something out of it, you must deserialize and then get the value from it.
dynamic foo = JsonConvert.DeserializeObject<dynamic>(theJson);
var textToLoad = foo.value.ToString();
You must deserialize to something in order to inspect and get properties from it.
[Edit] - Perhaps I'm not understanding. But if you share code, I'll update my answer.

Is there a way to pass a list of JSON objects from JS to C#?

Something I'm confusing.
The Javascript is going to produce the following JSON data.
{type:"book" , author: "Lian", Publisher: "ABC"}
{type:"Newspaper", author: "Noke"}
This is only an example, actually I've got more than this.
Since I have common fields between different JSON data, so I don't know is it possible to pass this to C# at one time.
What I want to do is pass this to c# then do some processing, what is the best way to do? I'm using ASP.NET MVC2.
Thanks for your answer or hints.
The combination of the 2 JSON statements above are, together, not valid JSON. That being said, you will not be able to use the JavaScriptSerializer class to deserialize that data into c# structure directly. Instead you will have to do some manual parsing first, to either break it down into valid JSON or just do full on manual parsing.
What I would actually recommend is sending over valid JSON instead. You can accomplish this by doing something like this:
{list: [
{type:"book" , author: "Lian", Publisher: "ABC"},
{type:"Newspaper", author: "Noke"} ]
Hard to say exactly, since only you know the details of your use case. You can send this data over using a traditional 'ajax' request. This is very easy to do with out any of the many JS libraries out there, but I would recommend just going with one anyway - they offer higher level constructs that are easier to use (and address cross-browser idiosyncrasies).
Since you are using ASP.NET MVC2, I would recommend jQuery. Microsoft is now backing jQuery as their JS library of choice and even make it default for new web projects.
Once you pass the above JSON to C#, you can deserialize it by doing something like this:
JavaScriptSerializer serializer = new JavaScriptSerializer();
var result = serialzer.Deserialize<Dictionary<string, object>>(postedJSONData);
Your result will then have a structure that looks like this, in C#:
Dictionary<string, object> result =>
{ "list" => object },
object => List<object>,
List<object> => Dictionary<string, object>
{ "type" => "book", "author" => "Lian" } // etc
[
{type:"book" , author: "Lian", Publisher: "ABC"},
{type:"Newspaper", author: "Noke"}
]
Is still valid JSON (well actually keys need to be enclosed in " as well), so you can .push() into an array each time you create a JSON record.
var list = [];
// code doing other stuff
list.push({type:"book" , author: "Lian", Publisher: "ABC"});
// more code doing other stuff
list.push({type:"Newspaper", author: "Noke"})
Once your JSON list is constructed, you can send that list to the backend in one go.
You can also use the JavaScriptSerializer to deserialize your own custom type. Esentially you make a very simple type with all the properties of your json objects then call
JavaScriptSerializer serializer = new JavaScriptSerializer();
MyType result = serialzer.Deserialize<MyType>(JsonData);
You can also deserialize an array
MyType[] result = serialzer.Deserialize<MyType[]>(JsonData);

Categories

Resources