I have the following JSON string
{ "Params": [ { "name": "id","value": "1234567" },
{ "name": "class","value": "six"}
],
"type":"general"}
and equivalent class as below
public class class1
{
public Param[] Params { get; set; }
public string Type { get; set; }
}
public class Param
{
public string Name { get; set; }
public string Value { get; set; }
}
How can I search if there is an object with name as id in Params array and how to fetch its value?
Include Newtonsoft.Json
using Newtonsoft.Json;
Then deserialize your json string to an object of class1, then search using linq.
string json = "{\"Params\": [ { \"name\": \"id\",\"value\": \"1234567\" },{ \"name\": \"class\",\"value\": \"six\"}],\"type\":\"general\"}";
// convert to object
var jsonObject = JsonConvert.DeserializeObject<class1>(json);
// filter
var result = jsonObject.Params.Where(p=> p.Name == "id" && p.Value == "1234567");
The Json.net documentation has a pretty good example you can use as well. It shows a way to do without necessarily converting to a C# object. See below
https://www.newtonsoft.com/json/help/html/queryinglinqtojson.htm
Related
For example, items in expressions may be a string, number, or an object. How to deserialize it to.NET object. I do not know how to define .NET class and do not know to implement JsonConverter.
{
"target": {
"propertyName": "AlertObjectInfo",
"valueType": "string"
},
"source": {
"operationName": "concat",
"expressions": [
"aa",
"bb",
2,
{
"operationName": "concat",
"expressions": [
"Name",
"Tom"
]
},
{
"operationName": "Add",
"expressions": [
3,
4
]
}
]
}
}
Convert your json payload to a corresponding C# object(s). You can do this in Visual Studio using the Paste Special option under the edit menu or as noted you can use an online tool to do the conversion.
This conversion will result in something like this based on your sample payload:
public class Root
{
[JsonPropertyName("target")]
public Target Target { get; set; }
[JsonPropertyName("source")]
public Source Source { get; set; }
}
public class Source
{
[JsonPropertyName("operationName")]
public string OperationName { get; set; }
[JsonPropertyName("expressions")]
public List<object> Expressions { get; set; }
}
public class Target
{
[JsonPropertyName("propertyName")]
public string PropertyName { get; set; }
[JsonPropertyName("valueType")]
public string ValueType { get; set; }
}
Then to deserialize the json into c# objects you'll make a call like the following.
System.Text.Json
JsonSerializer.Deserialize<Root>(json);
NewtonSoft
JsonConvert.DeserializeObject<Root>(json);
If you're using Newtonsoft you'll want to replace the [JsonPropertyName("target")] attributes with [JsonProperty("target")]
Is there a way in Unity to parse JSON string to a C# class that have a list of - lets suppose - string?
I have an application that get a lot of data from a server. That data comes in a JSON and it have a lot of fields. Some fields have another array in it (I know the ones who have an array inside and the ones who don't).
Knowing this I want to make it into a class so I can access it's parameters, [I can't create an array and try to access - for example - arr[0], because arr[0] may not be the field that I want - given that the array positions can change, but the field-key (or field-field-key if the array have an array inside) value will not]
{
"success": "1",
"menus": [
{
"id_menu": "506",
"nome": "Blog",
"tipo": "blog"
},
{
"id_menu": "510",
"nome": "Sobre",
"tipo": ""
},
{
"id_menu": "2407",
"nome": "(Projeto Quatro Artes)",
"tipo": ""
},
{
"id_menu": "2603",
"nome": "(Loja)",
"tipo": ""
},
{
"id_menu": "2687",
"nome": "(Material NA)",
"tipo": ""
},
{
"id_menu": "2818",
"nome": "(Forms)",
"tipo": ""
},
{
"id_menu": "2826",
"nome": "(PHP+PIZZA)",
"tipo": ""
},
{
"id_menu": "7728",
"nome": "(Image)",
"tipo": ""
},
{
"id_menu": "3239",
"nome": "(jc)",
"tipo": ""
},
{
"id_menu": "6024",
"nome": "(assinatura)",
"tipo": ""
}
]
}
The code above is one of the JSONS that I want to parse, and the code below is the class that I made to parse it. Now i just need to know how to do it.
[System.Serializable]
public class Menu
{
public string id_menu { get; set; }
public string nome { get; set; }
public string tipo { get; set; }
}
[System.Serializable]
public class Return
{
public string success { get; set; }
public List<Menu> menus { get; set; }
}
I know that JsonUtility.FromJson() can do the job if there isn't any lists, but with lists it just doesn't work
Also, trying to use JSONObject from Unity assets also doesn't work because I can't access return.menus.tipo (as an example) because it doesn't have an associative index.
you can do it in the following way:
var returnObj = JsonConvert.DeserializeObject<Return>(json);
In order for this to work, you need the following package: Newtonsoft.Json
The result is as follow:
I made a small console app, which shows you the way. It should be the same in Unity:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace IoException
{
[System.Serializable]
public class Menu
{
public string id_menu { get; set; }
public string nome { get; set; }
public string tipo { get; set; }
}
[System.Serializable]
public class Return
{
public string success { get; set; }
public List<Menu> menus { get; set; }
}
public class JsonExercise
{
public static void Main(string[] args)
{
var currentLine = Console.ReadLine();
var sb = new StringBuilder();
while (currentLine != "END")
{
sb.AppendLine(currentLine);
currentLine = Console.ReadLine();
}
var json = sb.ToString().Trim();
var returnObj = JsonConvert.DeserializeObject<Return>(json);
Console.WriteLine();
}
}
}
Notes about the console app, in case you want to try it:
When you enter the JSON, enter "END" as the last line, in order for the console app to stop reading.
For the input JSON, I used the one that you provided.
perhaps use Json.NET or another deserializer that has full support for arbitrary types?
public class MyClass
{
public string id_menu { get; set; }
public string nome { get; set; }
public string tipo { get; set; }
public List<string> my_list {get; set; }
}
var result = JsonConvert.DeserializeObject<MyClass>(json);
If you try to parse the Json via Unity, you can use the JsonUtility.FromJson(jsonString), it will parse the Json to an Object, that it can handle, but I never tried using with complex JSONs.
Or you can run through the json and search for the key value that you want, but it sure does increase on memory consumption.
JSON
{
"count": 3,
"value": [
{
"id": "AAAAAAAAAAAAA",
"description": "test1",
"name": "name1"
},
{
"id": "BBBBBBBBBB",
"description": "test2",
"name": "name2"
},
{
"id": "CCCCCCCCCCCC",
"description": "test3",
"name": "name3"
}
]
}
I have a code in my solution retrieving from a LIST api and giving the JSON above.
How can I use a LINQ to retrieve specific values? (e.g) I need to select name1 and I will get the id,description,name values.
I am using a dynamic variable in my code:
dynamic json = JObject.Parse(client.GetString().Result);
I'd been tinkering with other online guides the past few hours. However, can't get the result right.
Please help.
One solution would be to deserialize your JSON string into C# objects and then use Linq to get a specific object.
C# class definitions:
public class Content
{
[JsonProperty("count")]
public int Count { get; set; }
[JsonProperty("value")]
public List<Value> Values { get; set; }
public Content()
{
Values = new List<Value>();
}
}
public class Value
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
Deserializing and getting the object:
string json = #"{
""count"": 3,
""value"": [
{
""id"": ""AAAAAAAAAAAAA"",
""description"": ""test1"",
""name"": ""name1""
},
{
""id"": ""BBBBBBBBBB"",
""description"": ""test2"",
""name"": ""name2""
},
{
""id"": ""CCCCCCCCCCCC"",
""description"": ""test3"",
""name"": ""name3""
}
]
}";
Content content = JsonConvert.DeserializeObject<Content>(json);
Value value = content.Values.FirstOrDefault(x => x.Name.Equals("name1", StringComparison.InvariantCultureIgnoreCase));
First, you can create a class to represent a client:
public class Client
{
public string Id { get; set; }
public string Description { get; set; }
public string Name { get; set; }
}
With this class, you can use JObject.Parse (as you're already doing) to parse the JSON into something that can be queried, use SelectToken to pull out the value array and then use ToObject to convert that to a list of Clients. Here's what that looks like:
var jsonObject = JObject.Parse(json_source);
var jsonObjectValue = jsonObject.SelectToken("value");
var clients = jsonObjectValue.ToObject<List<Client>>();
Once you've got your clients variable, you can use a simple LINQ statement to find the one that is name1:
var clientWithName1 = clients.SingleOrDefault(x => x.Name == "name1");
In this case, clientWithName will be null if no such client was found.
Here's a dotnetfiddle that demonstrates a complete solution.
Create an object Client that has properties id, description and name. Deserialize the json into a list of these objects.
List<Client> clients = JsonConvert.Deserialize<List<Client>>(json_source);
string desc = clients[0].description;
Apparently with fiddling with my code I found an answer for myself.
Thanks for to the ones trying to help me for giving me ideas.
var requestWorkProcess = await client.GetStringAsync("my url");
var workProcessId = JObject.Parse(requestWorkProcess)["value"].Children<JObject>().FirstOrDefault(o => o["name"].ToString() == workProcess).GetValue("id");
I am getting JSON data by calling a service which format like :
[
[
{
"AgentStatus": "- Active",
"Basement": "None",
"BasementType": "",
"Baths": "4",
"BathsHalf": "1",
"Beds": "6"
},
[
"372010-1.jpg"
]
],
[
{
"AgentStatus": "- Active",
"Basement": "Finished,Full",
"BasementType": "FULL FINISHED",
"Baths": "2",
"BathsHalf": "1",
"Beds": "3"
},
[
"377388-1.jpg",
"377388-2.jpg",
"377388-12.jpg"
]
]
]
To parse this JSON i made class like :
public class RetsProperty
{
public PropertyAttributes PropAttributes { get; set; }
public string[] ImgUrls { get; set; }
}
public class PropertyAttributes
{
public string AgentStatus { get; set; }
public string Basement { get; set; }
public string BasementType { get; set; }
public string Baths { get; set; }
public string BathsHalf { get; set; }
public string Beds { get; set; }
}
And i have used Newtonsoft Json to deserialize JSON data
var retsPropertyItems = Newtonsoft.Json.JsonConvert.DeserializeObject<List<RetsProperty>>(propertyJsonString);
But it can't parse it returns below error :
I think it is because i can't able to create class properly.
So how can i format my class ?
Or is it possible to map the way i did ?
Thanks
You have really bad formatted JSON becouse it have array within array without property name. So you just should parse it carefully.
I came up with a solution that could be not so bad and easy to understand (If i understand your JSON format right). The idea is to wrap your JSON with property name and then parse his constuction.
You should wrap your JSON same way:
var wrappedText = #"{ ""Prop"": " + propertyJsonString + " }";
And then you can parse in with Newtonsoft Json:
var jsonData = JObject.Parse(wrappedText);
Now you have your JSON data and you should parse it manualy. I recommend you this way:
List<RetsProperty> RetsProperties = new List<RetsProperty>();
foreach (var prop in jsonData["Prop"])
{
RetsProperties.Add(new RetsProperty
{
ImgUrls = Newtonsoft.Json.JsonConvert.DeserializeObject<string[]>(prop.Last.ToString()),
PropAttributes = Newtonsoft.Json.JsonConvert.DeserializeObject<PropertyAttributes>(prop.First.ToString())
});
};
You should understand that it will work only if you have 2 array items in last array. Take a look at prop.First and prop.Last.
First of all you have a very strange JSON, but as you said you receive it from external service. You can parse such JSON using JArray and LINQ, but of course this method is very dependent on the structure of JSON.
var retsProperties = JArray.Parse(json)
.Select(item => new RetsProperty
{
PropAttributes = item.First.ToObject<PropertyAttributes>(),
ImgUrls = item.Last.ToObject<string[]>()
})
.ToList();
I've been playing with this for the past few days and I'm hoping someone could shed some light on what the issue could be.
I have this custom object that I created:
public class WorldInformation
{
public string ID { get; set; }
public string name { get; set; }
}
and this JSON data:
string world = "[{\"id\":\"1016\",\"name\":\"Sea of Sorrows\"}, {\"id\":\"1008\",\"name\":\"Jade Quarry\"},{\"id\":\"1017\",\"name\":\"Tarnished Coast\"},{\"id\":\"1006\",\"name\":\"Sorrow's Furnace\"},{\"id\":\"2014\",\"name\":\"Gunnar's Hold\"}]";
and I can sucessfully save the data in my custom object by deserializing it:
List<WorldInformation> worlds = JsonConvert.DeserializeObject<List<WorldInformation>>(world);
But...
When I create a custom object like this
public class EventItems
{
public string World_ID { get; set; }
public string Map_ID { get; set; }
public string Event_ID { get; set; }
public string State { get; set; }
}
and have JSON data like this:
string eventItem = "{\"events\":[{\"world_id\":1011,\"map_id\":50,\"event_id\":\"BAD81BA0-60CF-4F3B-A341-57C426085D48\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":50,\"event_id\":\"330BE72A-5254-4036-ACB6-7AEED05A521C\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"0AC71429-406B-4B16-9F2F-9342097A50AD\",\"state\":\"Preparation\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"C20D9004-DF6A-4217-BF25-7D6B5788A94C\",\"state\":\"Success\"}]}";
I get an error when I try to deserialize it
List<EventItems> events = JsonConvert.DeserializeObject<List<EventItems>>(eventItem);
The error message I get is:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[WebApplication1.EventItems]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'events', line 1, position 10.
Unforturnately there isn't a way to specify the root Json element like the XmlSerializer.
See How to deserialize JSON array with "root" element for each object in array using Json.NET?
public class EventItems
{
public EventItems()
{
Events = new List<EventItem>();
}
public List<EventItem> Events { get; set; }
}
public class EventItem
{
public string World_ID { get; set; }
public string Map_ID { get; set; }
public string Event_ID { get; set; }
public string State { get; set; }
}
Usage:
string eventItem = "{\"events\":[{\"world_id\":1011,\"map_id\":50,\"event_id\":\"BAD81BA0-60CF-4F3B-A341-57C426085D48\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":50,\"event_id\":\"330BE72A-5254-4036-ACB6-7AEED05A521C\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"0AC71429-406B-4B16-9F2F-9342097A50AD\",\"state\":\"Preparation\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"C20D9004-DF6A-4217-BF25-7D6B5788A94C\",\"state\":\"Success\"}]}";
var items = JsonConvert.DeserializeObject<EventItems>(eventItem);
In first case your json is array of objects, so deserialization into a list of your class type succeeds.
In second case, your json is an object, and its "events" property is set to an array of objects, so it cannot be deserialized into a list.
What you may do, is change your class declaration:
public class EventItem
{
public string World_ID { get; set; }
public string Map_ID { get; set; }
public string Event_ID { get; set; }
public string State { get; set; }
}
public class EventItems
{
public EventItem[] Events { get; set; }
}
And deserialize it:
EventItems events = JsonConvert.DeserializeObject<EventItems>(eventItem);
Simply remove the object events from the 2nd JSON string:
string eventItem = "[{\"world_id\":1011,\"map_id\":50,\"event_id\":\"BAD81BA0-60CF-4F3B-A341-57C426085D48\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":50,\"event_id\":\"330BE72A-5254-4036-ACB6-7AEED05A521C\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"0AC71429-406B-4B16-9F2F-9342097A50AD\",\"state\":\"Preparation\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"C20D9004-DF6A-4217-BF25-7D6B5788A94C\",\"state\":\"Success\"}]";
It seems that your JSON string is not the same in both examples.
On the first example, you're using a simple JSON array:
[
{
"id": "1016",
"name": "Sea of Sorrows"
},
{
"id": "1008",
"name": "Jade Quarry"
},
{
"id": "1017",
"name": "Tarnished Coast"
},
{
"id": "1006",
"name": "Sorrow's Furnace"
},
{
"id": "2014",
"name": "Gunnar's Hold"
}
]
And on the second example, you're assigning your array to an object (events):
{
"events":
[
{
"world_id": 1011,
"map_id": 50,
"event_id": "BAD81BA0-60CF-4F3B-A341-57C426085D48",
"state": "Active"
},
{
"world_id": 1011,
"map_id": 50,
"event_id": "330BE72A-5254-4036-ACB6-7AEED05A521C",
"state": "Active"
},
{
"world_id": 1011,
"map_id": 21,
"event_id": "0AC71429-406B-4B16-9F2F-9342097A50AD",
"state": "Preparation"
},
{
"world_id": 1011,
"map_id": 21,
"event_id": "C20D9004-DF6A-4217-BF25-7D6B5788A94C",
"state": "Success"
}
]
}