Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
i have a returned string looks like this
"{\"properties\":{\"item1\":{\"dataType\":\"string\"},\"item2\":{\"dataType\":\"string\"}},\"lastModified\":\"2021-12-09T18:20:29Z\"}"
i have tries to Deserialize by using dictionary but still not catching the data.
the most important data is just named inside the properties, item1, item2
System.Text.Json.JsonSerializer.Deserialize<IDictionary<string, object>>(jsonString)
and it' giving the folowing result
[0] [KeyValuePair]:{[properties, {"Item1":{"dataType":"string"},"item2":{"dataType":"string"}
Key [string]:"properties"
Value [object]:ValueKind = Object : "{"item1":{"dataType":"string"},"item2":{"dataType":"string"}
Key [string]:"lastModified"
[1] [KeyValuePair]:{[lastModified, 2021-12-09T19:00:12Z]}
You can deserialize the JSON string to an object by following these simple steps:
Create a C# class from the JSON data. To do this, copy the JSON string and go to VS, Edit, Paste Special, Paste JSON as Classes.
if successful, you will get a C# class like this one
public class Rootobject
{
public Properties properties { get; set; }
public DateTime lastModified { get; set; }
}
public class Properties
{
public Item1 item1 { get; set; }
public Item2 item2 { get; set; }
}
public class Item1
{
public string dataType { get; set; }
}
public class Item2
{
public string dataType { get; set; }
}
You can rename the classes to anything that make meaning to you.
The you can deserialize like this
var obj = JsonConvert.DeserializeObject<Rootobject>(
"{\"properties\":{\"item1\":{\"dataType\":\"string\"},\"item2\":{\"dataType\":\"string\"}},\"lastModified\":\"2021-12-09T18:20:29Z\"}");
Console.WriteLine(obj.properties.item2.dataType)// string
If you only need the value of dataType property and not the whole object, than you can use Linq to Json to get it without deserialization and object mapping.
The examples:
var obj = JObject.Parse("{\"properties\":{\"item1\":{\"dataType\":\"string\"},\"item2\":{\"dataType\":\"string\"}},\"lastModified\":\"2021-12-09T18:20:29Z\"}");
var fistItemDataTypeValue = (string)obj["properties"]?["item1"]["dataType"];
var secondItemDataTypeValue = (string)obj["properties"]?["item2"]["dataType"];
Getting values as list of strings (NOTES: if you already know the number of items in json):
var obj = JObject.Parse("{\"properties\":{\"item1\":{\"dataType\":\"string\"},\"item2\":{\"dataType\":\"string\"}},\"lastModified\":\"2021-12-09T18:20:29Z\"}");
var listOfValues = new List<string>();
for (int i = 1; i <= 2; i++)
{
listOfValues.Add((string)obj["properties"]?[$"item{i}"]["dataType"]);
}
! More about linq to json
Related
This question already has an answer here:
json deserialization to C# with dynamic keys [duplicate]
(1 answer)
Closed 4 months ago.
My JSON has this information:
[
{
"era_1":{"technology_cost":"10000"},
"era_2":{"technology_cost":"15000"},
"era_3":{"technology_cost":"20000"},
"era_4":{"technology_cost":"25000"},
"era_5":{"technology_cost":"30000"}
}
]
I want to do:
EraData = JsonConvert.DeserializeObject<List<ClassEra>>(JSON);
Being ClassEra
public class ClassEra
{
public string name { get; set; }
public string technology_cost { get; set; }
}
And obviously it doesn't work.
I don't understand the type of data that is coming out of the deserializer.
By the way I'm using Newtonsoft.
The json format is not what you are trying to capture as class object. Your targeted json should be :
[{"name":"era_1","technology_cost":"10000"},
{"name":"era_2","technology_cost":"15000"},
{"name":"era_3","technology_cost":"20000"},
{"name":"era_4","technology_cost":"25000"},
{"name":"era_5","technology_cost":"30000"}]
try this one
EraData = JsonConvert.DeserializeObject<List<Dictionary<string, ClassEra>>>(JSON);
And class will be
public class ClassEra
{
public string technology_cost { get; set; }
}
Fetching details
I prefer to use dictionary because time complexity of fetching value is O(1) by key like dic[key]
//By this :- get complete dictionary
var dic = EraData[0]; //and iterate by foreach loop
//by this you can get all technology cost:-
var technology_cost = EraData.SelectMany(x => x.Values);
Screenshots
Dictionary
Technology Cost
To expand a bit on what #Pradeep wrote, if you want to know the era name you could select it like this
var dict = JsonConvert.DeserializeObject<List<Dictionary<string, ClassEra>>>(json);
var eras = dict.SelectMany(x => x.Keys.Select(k => new ClassEra()
{
Name = k,
TechnologyCost = x[k].TechnologyCost
}));
public class ClassEra
{
public string Name { get; set; }
[JsonProperty("technology_cost")] public string TechnologyCost { get; set; }
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 11 months ago.
Improve this question
I am trying to save a JSON file in C# with variables from user input. I am using Visual Studio with Newtonsoft.Json. Does anyone know how to create a JSON object with variables of name, description, and code.
Assuming you are using the following class:
public class CustomClass {
public string Name { get; set; }
public string Job { get; set; }
public int Age { get; set; }
}
Saving class objects as JSON file:
var user = new CustomClass() {
Name = "John Wick",
Job = "Businessman",
Age = 42
};
var jsonString = JsonConvert.SerializeObject(user, Formatting.Indented);
File.WriteAllText(#"C:\temp\user.json", jsonString);
Loading JSON files and converting them to C# objects:
var jsonString = File.ReadAllText(#"C:\temp\user.json");
CustomClass? user = JsonConvert.DeserializeObject<CustomClass>(jsonString);
Additional:
By default, parsing will map the property names directly. Parsing the example from above to JSON would return:
{
"Name": "John Wick",
"Job": "Businessman",
"Age": 42
}
If you need to parse JSON objects, where the stored properties are different from the property names of your class, you can "rename" them by using property tags.
using Newtonsoft.Json;
public class CustomClass {
[JsonProperty("user_name")]
public string Name { get; set; }
[JsonProperty("user_job")]
public string Job { get; set; }
[JsonProperty("user_age")]
public int Age { get; set; }
}
When parsed, this will return the following output:
{
"user_name": "John Wick",
"user_job": "Businessman",
"user_age": 42
}
A sample for you:
void Main()
{
var data = new {
name ="Your Name",
description="This is my name",
code="007"
};
var json = JsonConvert.SerializeObject(data);
File.WriteAllText(#"c:\temp\myJson.json", json);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
My C# application has the below json which is deserialized to a dictionary which is assigned to values:
{
"armSpan": 1.8081974983215332,
"handPosition": {
"x": 1.23,
"y": 1.74,
"z": 2.05,
}
}
This is the code which deserializes:
var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
I want to assign data from it to various fields in my Size model. For armSpan I'm happy that the following works:
size.ArmSpan = decimal.Parse(values["armSpan"]);
I'm not sure how to get the values of x, y and z though. should it be something like
size.HandPosX = decimal.Parse(values["handPosition"]["x"]);
or
size.HandPosX = decimal.Parse(values["handPosition"].["x"]);
There are online converters to generate c# code based on your json (search for "JSON to C#"). With one of those, I made these classes based on the json you supplied (removed the extra comma in '"z": 2.05,'):
public partial class ClassYouDeserializeTo
{
[JsonProperty("armSpan")]
public double ArmSpan { get; set; }
[JsonProperty("handPosition")]
public HandPosition HandPosition { get; set; }
}
public partial class HandPosition
{
[JsonProperty("x")]
public double X { get; set; }
[JsonProperty("y")]
public double Y { get; set; }
[JsonProperty("z")]
public double Z { get; set; }
}
You can use them like this:
var values = JsonConvert.DeserializeObject<ClassYouDeserializeTo>(response);
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I have one JSON like:
In success response it is like:
{
statusCode: "200",
status: "Success",
data: [
{
empName: "Prashant",
empCode: 001
},
{
empName: "Jack",
empCode: 002
}
]
}
and In error response or if there is an exception while processing a request like:
{
statusCode: "400",
status: "Fail",
data: {
empId: "This field is mandatory"
}
}
How I can parse the response in both case? Now I am getting an exception while parsing the JSON.
The C# Class I used to parse the response is:
public class Employee
{
public string empName { get; set; }
public int empCode { get; set; }
}
public class Response
{
public string statusCode { get; set; }
public string status { get; set; }
public List<Employee> data { get; set; }
}
EDIT:
The exception details:
System.InvalidCastException: Specified cast is not valid.
You can use Newtonsoft.Json [https://www.newtonsoft.com/json]
When you install Newtonsoft.Json from NugetLibrary you can use code below,
String json = "{statusCode: \"200\",status: \"Success\",data: [{empName: \"Prashant\",empCode: 001},{empName: \"Jack\",empCode: 002}]}";
Response resp = JsonConvert.DeserializeObject<Response>(json);
Your normal response maps directly to classes you provided. And this is deserialized without any problem.
The problem emerges, when you try deserialize your error resopnse. It specifies empId which is not present in any of your classes. That is generating exception.
Also, in your normal response, you have list in data (indicated by square brackets [ and ]), in second, you don't have a list. This is also inconsistent and is causing exception.
In order to make it work, you have to modify your error response:
1) change empId to empName or add empId in your Employee class:
public class Employee
{
public string empId { get; set; }
public string empName { get; set; }
public int empCode { get; set; }
}
2) alter data field in JSON, so it will be an array:
{
statusCode: ""400"",
status: ""Fail"",
data: [{
empId: ""This field is mandatory""
}]
}
Finally, deserialize it with:
var normalObject = JsonConvert.DeserializeObject<Response>(normalJson);
var errorObject = JsonConvert.DeserializeObject<Response>(errorJson);
UPDATE
If you want statusCode only, make the type of data in Response class object, so it won't throw exception while parsing:
public class Response
{
public string statusCode { get; set; }
public string status { get; set; }
public object data { get; set; }
}
To get statusCode directly, use:
var statusCode = JsonConvert.DeserializeObject<Response>(normalJson).statusCode;
statusCode = JsonConvert.DeserializeObject<Response>(errorJson).statusCode;
If your objects are not fixed and data must be configurable then Newtonsoft.json has one feature that to be use here and that is [JsonExtensionData]. Read more
Extension data is now written when an object is serialized. Reading and writing extension data makes it possible to automatically round-trip all JSON without adding every property to the .NET type you’re deserializing to. Only declare the properties you’re interested in and let extension data do the rest.
So in your case your Response class will be
public class Response
{
public string statusCode { get; set; }
public string status { get; set; }
[JsonExtensionData]
public Dictionary<string, JToken> data;
}
All your data in data key will be collected in [JsonExtensionData] property.
You need to perform operations on [JsonExtensionData] property to get your key/value pair. like
public class Employee
{
public string empId { get; set; }
public string empName { get; set; }
public int empCode { get; set; }
}
And you can perform opration like
var json = "Your response";
JObject jObject = JObject.Parse(json);
var statusCode = jObject["statusCode"];
var status = jObject["status"];
var data = jObject["data"];
if (data.Type == JTokenType.Array)
{
var arrayData = data.ToObject<List<Employee>>();
}
else
if (data.Type == JTokenType.Object)
{
var objData = data.ToObject<Employee>();
}
JsonConvert.DeserializeObject<T>(variableHoldingJsonString);
where T is the type of the object/list you want the main to be.
This will give the desired result.
However there is a lot of help out there already.
I like to use the Newtonsoft package from NuGet. It works really well.
Newtonsoft.Json.JsonConvert.DeserializeObject<T>(Response);
T is the object of choice (you can special paste a JSON string to create a class if you have the web development kit active in VS2017).
The class structure has to match that of the JSON string. In the first example, a list of Employee data has empName and empCode so it will convert fine, but in the second example you haven't catered for empId so it doesn't know how to parse it.
Depending on status code you need different classes for deserialization. Use the following code to extract statusCode and deserialize string later to different object using your approach (Newtonsoft.json nuget is used):
dynamic js = JObject.Parse(str);
var code = js.statusCode;
public partial class Response
{
[JsonProperty("statusCode")]
public long StatusCode { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("data")]
public Employee[] Data { get; set; }
}
public partial class Employee
{
[JsonProperty("empName")]
public string EmpName { get; set; }
[JsonProperty("empCode")]
public long EmpCode { get; set; }
[JsonProperty("empId")]
public string EmpId { get; set; }
}
var ResponseJSON= JsonConvert.DeserializeObject<Response>(normalJson);
above class will help you to parse your json. you just need to check for Emplid is null or empty base on that you can simply do your work what you need.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Platform: C#
IDE: Visual Studio 2010
I am new to Linq and trying to filter a Json object using it. Any suggestions?
Here is the code:
string jsonGetData = objstats.getData_Emp(lblEmp.Text,lblYear.Text);
//JavaScriptSerializer strJsonSer = new JavaScriptSerializer();
var lstEmpAnalysis = JsonConvert.DeserializeObject<empAnalysis>(jsonGetData);
Now, from the above lstEmpAnalysis, I need to filter data on first table of the class empAnalysis where one of its index contains countries and show only those countries data being used in filter which is shown below :
public class empAnalysis
{
public List<List<object>> Table { get; set; }
public List<List<double>> Table1 { get; set; }
public List<List<object>> Table2 { get; set; }
}
So, any suggestions?
Input comes in this way :
Table
[0][0] : Abc
[0][1] : India
[0][2] : Engineer
[1][0] : Xyz
[1][1] : UK
[1][2] : Support Engineer
And what I want to filter is only the data which contains UK.
If you always know that second parameter of your table is the country you can do it like this :
var items= from item in empAnalysis.Table where item[1]=="UK" select item;
Although I always prefer to work with a strong typed object here as I mentioned in my comment :
For example :
public class Employee{
public string Name{get;set;}
public string Country{get;set;}
public string JobTitle{get;set;}
}
and
public class empAnalysis
{
public List<Employee> Table { get; set; }
public List<List<double>> Table1 { get; set; }
public List<List<object>> Table2 { get; set; }
}
then we could write :
var items= from employee in empAnalysis.Table where employee.Country=="UK" select item;
BTW for the purpose of clarity we can do something like this either :
var people=from item in empAnalysis.Table select new {
Title=item[0],
Country=item[1],
JobTitle=item[2],
};
var peopleFromUK=from person in people where person.Country=="UK";
Although you should be advised that you are getting a list of anonymous typed objects that have Title,Country and JobTitle properties.
UPDATE:
Here's a test that I wrote using NUnit and It passes.
[TestFixture]
public class LinqToObjectTests
{
[Test]
public void ThereShouldBeOnlyOneListForUK()
{
var list = new List<List<object>>
{
new List<object>(),
new List<object>()
};
list[0].Add("Name");
list[0].Add("UK");
list[0].Add("Title");
list[1].Add("Name");
list[1].Add("NOT UK");
list[1].Add("Title");
var query = from item in list where item[1] == "UK" select item;
Assert.AreEqual(1, query.Count());
}
}