How to write the value of one json property in one line? - c#

It is necessary to write value of "Coordinates" property in json without hyphenation for the following lines, not using ToString() (without converting the value to a string). The desired result is shown below.
{
"Id": null,
"Style": "1234",
"Geometry": {
"Type": "Polygon",
"Coordinates": [[[47541.470259278358,6846.8710054924586],[47540.359922950891,6845.4552435801925],[47541.470259278358,6846.8710054924586]]],
"Properties": [
{
"PointType": "Straight"
},
{
"PointType": "Straight"
},
{
"PointType": "Straight"
}
]
}
}
but not:
{
"Id": null,
"Style": "1234",
"Geometry": {
"Type": "Polygon",
"Coordinates": "[[[47541.470259278358,6846.8710054924586],[47540.359922950891,6845.4552435801925],[47541.470259278358,6846.8710054924586]]]",
"Properties": [
{
"PointType": "Straight"
},
{
"PointType": "Straight"
},
{
"PointType": "Straight"
}
]
}
}
A function that serializes the corresponding class object in json:
JToken ToJson()
{
using (var writer = new JTokenWriter()) {
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, this);
return writer.Token;
}
}

it seems your second case contains Coordinates property as serialized string.
why should not use
var string = JsonConvert.SerializeObject(YourObject) ?
But you should install https://www.nuget.org/packages/Newtonsoft.Json/ first
You could use string type for properties where you need double quotes and use array or number if you don't need it

Related

How to deserialize a json array with multiple data types?

I now need to deserialize a JSON that looks like this:
{
"arguments": {
"game": [
"--username",
"--version",
"--assetsDir",
{
"rules": [
{
"action": "allow",
"features": {
"is_demo_user": true
}
}
],
"value": "--demo"
},
{
"rules": [
{
"action": "allow",
"features": {
"has_custom_resolution": true
}
}
],
"value": [
"--width",
"--height"
]
}
]
}
}
As you can see, the array named "game" has both "value" and "object" in it. (But the fact is WORSE than this example, the number of elements is NOT certain)
And the data type of arguments.game[*].value is NOT certain, too.
I used to use classes to describe it, but deserialization failed.
Can't seem to describe an array with multiple element types with a class?
I am using Json.NET. Is there any way to deserialize this "game" array.
Thanks.
Is it a requirement to deserialize to an instance of a class? You could use an ExpandoObject:
using System.Dynamic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
Console.WriteLine("Hello, World!");
string json = #"{
""arguments"": {
""game"": [
""--username"",
""--version"",
""--assetsDir"",
{
""rules"": [
{
""action"": ""allow"",
""features"": {
""is_demo_user"": true
}
}
],
""value"": ""--demo""
},
{
""rules"": [
{
""action"": ""allow"",
""features"": {
""has_custom_resolution"": true
}
}
],
""value"": [
""--width"",
""--height""
]
}
]
}
}";
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, expConverter);
The obj variable will contain the result of the JSON conversion, then you can traverse the dynamic object in code.
For example, to get a list of strings under 'game':
IList<object> list = new List<object>(obj.arguments.game);
foreach (object str in list)
{
if (str as string != null)
{
Console.WriteLine(str as string);
}
}

Json.net serializing same type in a different manner

I want to serialize an object using json.net and c#. For that i have created a custom contract resolver that extends DefaultContractResolver class and also i have override the CreateProperties method. My class is something like
public class Hierarchy{
[JsonProperty("id")]
public int Id{get;set;}
[JsonProperty("parentId")]
public int ParentId{get;set;}
[JsonProperty("nodes")]
public List<Hierarchy> Nodes{get;set;}
}
Now i have an object of this class
{
"id": 3585,
"parentId": 0,
"nodes": [
{
"id": 3586,
"parentId": 3585,
"nodes": [
{
"id": 3587,
"parentId": 3586,
"nodes": null
}
]
},
{
"id": 3599,
"parentId": 3585,
"nodes": [
{
"id": 3600,
"parentId": 3599,
"nodes": null
},
{
"id": 3601,
"parentId": 3599,
"nodes": null
},
{
"id": 3602,
"parentId": 3599,
"nodes": null
},
{
"id": 3603,
"parentId": 3599,
"nodes": null
}
]
},
{
"id": 3744,
"parentId": 3585,
"nodes": null
}
]
}
Now my CustomDefaultResolver class is something like
public class CustomRetrieveResponseResolver : DefaultContractResolver
{
private readonly IList<string> _propertiesToInclude;
public CustomRetrieveResponseResolver(IList<string> propertiesToInclude , Type objType)
{
_propertiesToInclude = propertiesToInclude;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
// some code here
}
}
I'm passing a list of strings to the constructor which has the name of the properties I want to include in the final object. For example if propertiesToInclude = { "id" } i will get output
{ "id" : 3585 }
Also when propertiesToInclude = { "id" , "nodes" } i will get the entire object. I know that json.net will bind some contract with Type of object so all the Hierarchy type object will be serializing in the same manner.
So When propertiesToInclude = { "nodes.id" } is something like this i want an output
{
"nodes" : [
{
"id": 3586
},
{
"id": 3599
},
{
"id": 3744
}
]
}
But I'm getting
{
"nodes" : [
{
"nodes":null
},
{
"nodes":null
},
{
"nodes": null
}
]
}
This means I want to serialize the outer Hierarchy type and the inner Hierarchy type in a different way. I know that CreateProperties will be going to call only once and that time it will bind some contract or way of serializing Hierarchy Type object and it will use the same contract for every Hierarchy Type object independent of its position in the object.
So is there any way of defining different contracts ( or way of serializing) for the same Type occurring at different hierarchies in the same object?

Deserialize json array in Xamarin [duplicate]

This question already has answers here:
How to auto-generate a C# class file from a JSON string [closed]
(3 answers)
Closed 1 year ago.
I want to Deserialise this json file in my Xamarin android App to only get the coordinates.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "6849033",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
6.562265,
40.36426
],
[
6.5622743,
40.3642745
],
[
6.5622944,
40.3642897
],etc...
Here is my approach with my class
public class Cadastre
{
public List<List<List<List<float>>>> coordinates { get; set; }
public Cadastre()
{
}
}
And finally here my code to Deserialize my json file
string responseFinished = await GetJson();
Cadastre c = JsonConvert.DeserializeObject<Cadastre>(responseFinished);
I tried many solutions but my coordinates are still null.
If anyone has a solution or a lead I would be grateful.
try this
var jsonObject=JObject.Parse(json);
var coordinates = ((JArray)jsonObject["features"][0]["geometry"]["coordinates"][0][0]).Select(c => new { One = c[0], Two = c[1]}).ToList();
result
[
{
"One": 6.562265,
"Two": 40.36426
},
{
"One": 6.5622743,
"Two": 40.3642745
},
{
"One": 6.5622944,
"Two": 40.3642897
}
]
or if you want to deserialize your way
List<List<List<List<float>>>> coordinates = ((JArray)jsonObject["features"][0]["geometry"]["coordinates"]).ToObject<List<List<List<List<float>>>>>();
result
[
[
[
[
6.562265,
40.36426
],
[
6.5622745,
40.364273
],
[
6.5622945,
40.36429
]
]
]
]

MongoDB BsonDocument - Serialize JSON as key-object

I have a doubt if it is possible to serialize a collection of BsonDocument results as a JSON pair of key objects.
For example, I attach a piece of code that creates a collection of BsonDocument with and _id and name as fields,
using MongoDB.Bson;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ExampleBsonDocumentSerializeToJsonAsArray
{
class Program
{
static void Main(string[] args)
{
BsonDocument[] data = new BsonDocument[]{
new BsonDocument {
{ "_id" , "1" },
{ "name" , "name_1" },
{ "description" , "description_1" },
}
,new BsonDocument {
{ "_id" , "2" },
{ "name" , "name_2" },
{ "description" , "description_2" },
}
,new BsonDocument {
{ "_id" , "3" },
{ "name" , "name_3" },
{ "description" , "description_3" },
}
};
Console.WriteLine(data.ToJson());
}
}
}
List 1.1
The piece from the list 1.1 shows it gives output as a JSON array of objects:
[{
"_id": "1",
"name": "name_1",
"description": "description_1"
}, {
"_id": "2",
"name": "name_2",
"description": "description_2"
}, {
"_id": "3",
"name": "name_3",
"description": "description_3"
}]
Having the field '_id' as the key of the collection, I would like to serialize it as a set of key-object JSON instead of an array of objects. The result of serialized JSON should be like this,
{
"1": {
"name": "name_1"
, "description": "description_1"
},
"2": {
"name": "name_2"
, "description": "description_2"
},
"3": {
"name": "name_3"
, "description": "description_3"
}
}
I don't know whether is this possible or not.
You can convert BsonDocument to Dictionary via System.Linq.
using System.Linq;
var kvp = data.AsEnumerable()
.ToDictionary(x => x["_id"], x => new { name = x["name"], description = x["description"] });
Console.WriteLine(kvp.ToJson());
Sample program

Search for a nested value inside of a JSON.net object in C#

I've got a JSON stream coming back from a server, and I need to search for a specific value of the node "ID" using JSON.net to parse the data.
And I can almost make it work, but not quite because the results coming back are deeply nested in each other -- this is due to the fact that I'm getting a folder structure back. I've boiled the JSON down to a much simpler version. I'm getting this:
{
"data": {
"id": 0,
"name": "",
"childFolders": [{
"id": 19002,
"name": "Locker",
"childFolders": [{
"id": 19003,
"name": "Folder1",
"childFolders": [],
"childComponents": [{
"id": 19005,
"name": "route1",
"state": "STOPPED",
"type": "ROUTE"
}]
}, {
"id": 19004,
"name": "Folder2",
"childFolders": [],
"childComponents": [{
"id": 19008,
"name": "comm1",
"state": "STOPPED",
"type": "COMMUNICATION_POINT"
}, {
"id": 19006,
"name": "route2",
"state": "STOPPED",
"type": "ROUTE"
}, {
"id": 19007,
"name": "route3",
"state": "STOPPED",
"type": "ROUTE"
}]
}],
"childComponents": []
}],
"childComponents": []
},
"error": null
}
I can almost get there by going:
var objects = JObject.Parse(results);
var subobjects = objects["data"]["childFolders"][0]["childFolders"][1];
I can see in the debug view that it'll parse the object, but won't let me search within.
My ultimate goal is to be able to search for "route3" and get back 19007, since that's the ID for that route. I've found some results, but all of them assume you know how far nested the object is. The object I'm searching for could be 2 deep or 20 deep.
My ultimate goal is to be able to search for "route3" and get back 19007
You can use linq and Descendants method of JObject to do it:
var dirs = JObject.Parse(json)
.Descendants()
.Where(x=>x is JObject)
.Where(x=>x["id"]!=null && x["name"]!=null)
.Select(x =>new { ID= (int)x["id"], Name = (string)x["name"] })
.ToList();
var id = dirs.Find(x => x.Name == "route3").ID;
You can use the SelectToken or SelectTokens functions to provide a JPath to search for your desired node. Here is an example that would provide you the route based on name:
JObject.Parse(jsonData)["data"].SelectToken("$..childComponents[?(#.name=='route3')]")
You can find more documentation on JPath here
Simply write a recursive function:
private Thing FindThing(Thing thing, string name)
{
if (thing.name == name)
return thing;
foreach (var subThing in thing.childFolders.Concat(thing.childComponents))
{
var foundSub = FindThing(subThing, name);
if (foundSub != null)
return foundSub;
}
return null;
}
class RootObject
{
public Thing data { get; set; }
}
class Thing
{
public int id { get; set; }
public string name { get; set; }
public List<Thing> childFolders { get; set; } = new List<Thing>();
public List<Thing> childComponents { get; set; } = new List<Thing>();
}
And using it:
var obj = JsonConvert.DeserializeObject<RootObject>(jsonString);
var result = FindThing(obj.data, "route3");

Categories

Resources