Deserialize nested, complex json object to just a string c# - c#

I have JSON which looks like:
{
"name": "foo",
"settings": {
"setting1": true,
"setting2": 1
}
}
I know how to use json2csharp.com to create the C# classes to deserialize this. They looks like:
public class Settings
{
public bool settings1 { get; set; }
public int settings2 { get; set; }
}
public class RootObject
{
public string name { get; set; }
public Settings settings { get; set; }
}
but what I want is to simply deserialize it into
public class RootObject
{
public string name { get; set; }
public string settings { get; set; }
}
i.e., all of the "setting" JSON just needs to be saved as a string--the structure of that JSON is not consistent. How can that be done? Thanks!

You could use a JToken to capture your unknown settings during deserialization, then use a second property to allow you to access that JSON as a string if you need to.
Set up your class like this:
public class RootObject
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonIgnore]
public string Settings
{
get { return SettingsToken != null ? SettingsToken.ToString(Formatting.None) : null; }
set { SettingsToken = value != null ? JToken.Parse(value) : JValue.CreateNull(); }
}
[JsonProperty("settings")]
private JToken SettingsToken { get; set; }
}
Then deserialize as usual:
var root = JsonConvert.DeserializeObject<RootObject>(json);
The Settings property will contain the settings part of the JSON as a string. If you reserialize the object back to JSON then the settings will retain whatever structure it had before.
You can also change the Settings property to some other JSON string, as long as it is well-formed. (If it isn't, then an exception will be thrown immediately.)
Here is a round-trip demo: https://dotnetfiddle.net/thiaWk

Try using Newtonsoft.Json plus LINQ:
string jsonText = #"{
'name': 'foo',
'settings': {
'settings1': true,
'settings2': 1
}
}";
JObject jObj = JObject.Parse(jsonText);
var setting = jObj.Descendants()
.OfType<JProperty>()
.Where(p => p.Name == "settings")
.First()
.Value.ToObject<Settings>();

Try this:
public class RootObject
{
public string name { get; set; }
public Dictionary<string,object> settings { get; set; }
}
Fiddle:
https://dotnetfiddle.net/QN3nWL

I have just this solution:
public class RootObject
{
public string name { get; set; }
public Settings settings { get; set; }
public string strSettings { get; set; } <--------
}
and
var data= Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(json);
data.strSettings = Newtonsoft.Json.JsonConvert.SerializeObject(data.settings);

Related

How to deserialize root JSON dynamic property name in C#? [duplicate]

I've got the following json document:
{
"name": "bert",
"Bikes": {
"Bike1": {
"value": 1000,
"type": "Trek"
},
"Bike2": {
"value": 2000,
"type": "Canyon"
}
}
}
With potentially other bikes like Bike3...BikeN. I want to deserialize to C# objects. Problem is that in the deserialization step the bikes data is completely lost, resulting in a null Bikes collection.
Code to reproduce:
[Test]
public void FirstCityJsonParsingTest()
{
var file = #"./testdata/test.json";
var json = File.ReadAllText(file);
var res = JsonConvert.DeserializeObject<Person>(json);
Assert.IsTrue(res.Name == "bert");
// next line is failing, because res.Bikes is null...
Assert.IsTrue(res.Bikes.Count == 2);
}
public class Bike
{
public string Id { get; set; }
public int Value { get; set; }
public string Type { get; set; }
}
public class Person
{
public string Name { get; set; }
public List<Bike> Bikes { get; set; }
}
To fix this problem a change in the used model is necessary. But what change is needed here to fill the bikes data correctly?
Note: Changing the input document is not an option (as it's a spec)
Your code structure is not reflecting your json. Common approach to deserializing json with dynamic property names is to use Dictionary<string, ...> (supported both by Json.NET and System.Text.Json). Try the following:
public class Bike
{
public int Value { get; set; }
public string Type { get; set; }
}
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
public Dictionary<string, Bike> Bikes { get; set; }
}
Person.Bikes should be changed to Dictionary<string, Bike> (also Bike.Id property is not needed) cause Bikes json element is not an array but object.

Deserialize json object with dynamic items in C#

I've got the following json document:
{
"name": "bert",
"Bikes": {
"Bike1": {
"value": 1000,
"type": "Trek"
},
"Bike2": {
"value": 2000,
"type": "Canyon"
}
}
}
With potentially other bikes like Bike3...BikeN. I want to deserialize to C# objects. Problem is that in the deserialization step the bikes data is completely lost, resulting in a null Bikes collection.
Code to reproduce:
[Test]
public void FirstCityJsonParsingTest()
{
var file = #"./testdata/test.json";
var json = File.ReadAllText(file);
var res = JsonConvert.DeserializeObject<Person>(json);
Assert.IsTrue(res.Name == "bert");
// next line is failing, because res.Bikes is null...
Assert.IsTrue(res.Bikes.Count == 2);
}
public class Bike
{
public string Id { get; set; }
public int Value { get; set; }
public string Type { get; set; }
}
public class Person
{
public string Name { get; set; }
public List<Bike> Bikes { get; set; }
}
To fix this problem a change in the used model is necessary. But what change is needed here to fill the bikes data correctly?
Note: Changing the input document is not an option (as it's a spec)
Your code structure is not reflecting your json. Common approach to deserializing json with dynamic property names is to use Dictionary<string, ...> (supported both by Json.NET and System.Text.Json). Try the following:
public class Bike
{
public int Value { get; set; }
public string Type { get; set; }
}
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
public Dictionary<string, Bike> Bikes { get; set; }
}
Person.Bikes should be changed to Dictionary<string, Bike> (also Bike.Id property is not needed) cause Bikes json element is not an array but object.

Object is not populated with the JSON data when deserialized with NewtonSoft

using Telerik.Newtonsoft.Json;
MVC Controller:
public ActionResult Index()
{
string responseStr = GetJSON();
var jObject = JsonConvert.DeserializeObject<TheViewModel>(responseStr);
if (jObject == null)
{
return Content("");
}
return View("Default", jObject);
}
Temporary hard coded JSON method:
public string GetJSON() //to be replaced after testing
{
string json = #"{
'name': 'Trial 11.7',
'id': 2599,
'version': '11.7',
'product_id': '1040',
'time_of_execution': '2017-08-07T22:15:38.000Z',
'site_url': 'http://something.com/',
'mc_gem': '11.7',
'suite_gem': '11.7',
'passing_percentage': 95.65,
'failing_percentage': 4.35
}";
return json;
}
The model:
public class TheViewModel
{
public class RootObject
{
public string name { get; set; }
public int id { get; set; }
public string version { get; set; }
public string product_id { get; set; }
public string time_of_execution { get; set; }
public string site_url { get; set; }
public string mc_gem { get; set; }
public string suite_gem { get; set; }
}
}
The problem is that I get the following as the value when I step through the code:
jObject {Master.Project.Mvc.Models.TheViewModel} Master.Project.Mvc.Models.TheViewModel
For some reason I am not getting the JSON deserialized into the object. It is probably something simple, but I am not seeing it.
I receive no error message to help determine the issue inside the controller.
Any help would be appreciated.
You're trying to convert the JSON to an object of type TheViewModel when it's looking for a type of RootObject
You can fix this by either moving all of the fields in RootObject out and into TheViewModel or by calling ...DeserializeObject<TheViewMode.RootObject>(respon‌​seStr);
Refactor your code, extract the 'RootObject' class to its own file (or move it so that it is not defined under a class.) will solve the problem.

Getting json value from httpclient post request

I am trying to get the modhash value from a returned json string, I have set my getter/setter
public string mod_hash { get; set; }
I am using httclient, how can I get the json value of mod_hash
To post data:
/
Try with the below one.
To deserialize,you need to create the proper class structure for the json string. As per your json string, i have created here. Try and let us know if you have still issues.
public class RootObject
{
public Json json { get; set; }
}
public class Json
{
public List<object> errors { get; set; }
public Data data { get; set; }
}
public class Data
{
public bool need_https { get; set; }
public string modhash { get; set; }
public string cookie { get; set; }
}
And to test if it is correct or not here i have the program to get the "modhash" property value from your json string.
class Program
{
static void Main(string[] args)
{
string jsonstring = #"{ ""json"": {""errors"": [],""data"": { ""need_https"": true, ""modhash"": ""valuehereremoved"",""cookie"": ""valuehereremoved"" } } }";
var serializer = new JavaScriptSerializer();
var jsonObject = serializer.Deserialize<RootObject>(jsonstring);
Console.WriteLine("modhash : " + jsonObject.json.data.modhash);
Console.Read();
}
}
OUTPUT
Hope it solves your problem.

Json.net deserialization is returning an empty object

I'm using the code below for serialization.
var json = JsonConvert.SerializeObject(new { summary = summary });
summary is a custom object of type SplunkDataModel:
public class SplunkDataModel
{
public SplunkDataModel() {}
public string Category { get; set; }
public int FailureCount { get; set; }
public Dictionary<string, SplunkError> FailureEntity { get; set; }
public Dictionary<string, string> JobInfo { get; set; }
public string JobStatus { get; set; }
public int SuccessCount { get; set; }
public List<string> SuccessEntity { get; set; }
public int TotalCount { get; set; }
}
Serialization results in the JSON below:
{
"summary": {
"Category": "category",
"JobStatus": "Failure",
"JobInfo": {
"Course processing failed": ""
},
"TotalCount": 0,
"SuccessCount": 0,
"FailureCount": 0,
"FailureEntity": {},
"SuccessEntity": []
}
}
Now, for unit testing purposes, I need to deserialize it, but the code below is returning an object with empty values. Where am I going wrong?
var deserialized = JsonConvert.DeserializeObject<SplunkDataModel>(contents);
On my side, it was because I had no public setter for my properties.
Instead of having
public class MyClass
{
public int FileId { get; }
}
I should have
public class MyClass
{
public int FileId { get; set; }
}
silly mistake that cost me hours....
When you serialized your SplunkDataModel to JSON, you wrapped it in an object with a summary property. Hence, when you deserialize the JSON back to objects, you need to use the same structure. There are several ways to go about it; they all achieve the same result.
Declare a class to represent the root level of the JSON and deserialize into that:
public class RootObject
{
public SplunkDataModel Summary { get; set; }
}
Then:
var deserialized = JsonConvert.DeserializeObject<RootObject>(contents).Summary;
Or, deserialize by example to an instance of an anonymous type, then retrieve your object from the result:
var anonExample = new { summary = new SplunkDataModel() };
var deserialized = JsonConvert.DeserializeAnonymousType(contents, anonExample).summary;
Or, deserialize to a JObject, then materialize your object from that:
JObject obj = JObject.Parse(contents);
var deserialized = obj["summary"].ToObject<SplunkDataModel>();

Categories