Deserialize JSON Object C# with Newtonsoft - c#

I need to deserialize the following:
{"result":{"success":true,"value":"8cb2237d0679ca88db6464eac60da96345513964"}}
to a C# object using Newtonsoft.Json
WebClient wc = new WebClient();
var json = wc.DownloadString(url);
Worker w = JsonConvert.DeserializeObject<Worker>(json);
Here is the class code:
public class Worker
{
[JsonProperty("success")]
public string success { get; set; }
[JsonProperty("value")]
public string value { get; set; }
}
The code does not error out, but the success and value are null.

You're missing the outer object.
public class Worker
{
[JsonProperty("result")]
public Result Result { get; set; }
}
public class Result
{
[JsonProperty("success")]
public string Success { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}

You don't need any class and can make use of dynamic keyword
string json = #"{""result"":{""success"":true,""value"":""8cb2237d0679ca88db6464eac60da96345513964""}}";
dynamic dynObj = JsonConvert.DeserializeObject(json);
Console.WriteLine("{0} {1}", dynObj.result.success, dynObj.result.value);

I'm not familiar with that library, but success and result look to be both properties of the object "result"
Have you tried [JsonProperty("result.success")]?
Edit: Well, regardless it looks like a scoping issue. After viewing the documentation, this is my new suggestion:
public class Result{
[JsonProperty("result")]
public Worker result { get; set; }
}
then Json.Convert.Deserialize<Result>(json) instead.

Related

How to deserialize json object with no parent class?

I'm trying and failing to write a program that will make an API call and then turn the returned items into objects that fit my model. Specifically I can't make it deserealize, and I suspect it has something to do with how the json is return compared to what my model looks like.
The data I'm trying to get looks like this;
https://api.nasa.gov/planetary/apod?start_date=2022-03-01&end_date=2022-03-08&api_key=DEMO_KEY
As you can see, it consists of an array of items, but there is no name for the array items. When I paste this into the Get-model with Paste JSON as Classes, I get this;
public class GetApodItemsResult
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public string copyright { get; set; }
public string date { get; set; }
public string explanation { get; set; }
public string hdurl { get; set; }
public string media_type { get; set; }
public string service_version { get; set; }
public string title { get; set; }
public string url { get; set; }
}
My entire code works just fine up until I need to serialize the JSON with this line:
var responseObject = await response.Content.ReadFromJsonAsync<GetApodItemsResult>();
, where I get this message;
System.Text.Json.JsonException: 'The JSON value could not be converted to UnnamedSpaceProject.Models.GetApodItemsResult.
Interestingly I know that the code works on a spotify api call, so the code really should work largely the same, which leads me to believe that the problem is with how the JSON is formatted.
How do I get around that? Because I don't see a way to have the root object contain an unnamed array.
Your GetApodItemsResult class is not a valid class to deserialize the content you get from server, the correct deserialization type will be List<Class1> or Class1[]
var responseObject = await response.Content.ReadFromJsonAsync<List<Class1>>();
I recommend you to use more meaningful name instead of Class1 you can name it Apod (acronym for Astronomy Picture of the Day)
Full working code:
using System.Text.Json;
using System.Text.Json.Serialization;
HttpClient client = new HttpClient();
const string BaseUrl = #"https://api.nasa.gov/";
var response = await client.GetAsync($"{BaseUrl}planetary/apod?start_date=2022-03-01&end_date=2022-03-08&api_key=DEMO_KEY");
if ((response.StatusCode != System.Net.HttpStatusCode.OK))
{
Console.Error.WriteLine("field to fetch data from server");
}
var responseBody = await response.Content.ReadAsStringAsync();
var pictuersList = JsonSerializer.Deserialize<List<Apod>>(responseBody);
Console.WriteLine($"there is {pictuersList?.Count} apod downloaded successflly");
Console.WriteLine("done");
public class Apod
{
[JsonPropertyName("copyright")]
public string Copyright { get; set; } = "";
[JsonPropertyName("date")]
public string Date { get; set; } = "";
[JsonPropertyName("explanation")]
public string Explanation { get; set; } = "";
[JsonPropertyName("hdurl")]
public string Hdurl { get; set; } = "";
[JsonPropertyName("media_type")]
public string MediaType { get; set; } = "";
[JsonPropertyName("service_version")]
public string ServiceVersion { get; set; } = "";
[JsonPropertyName("title")]
public string Title { get; set; } = "";
[JsonPropertyName("url")]
public string Url { get; set; } = "";
}
The object your JSON containing is not some container with the array in it, it IS the array. So, the correct code would be like this:
var responseObject = await response.Content.ReadFromJsonAsync<Class1[]>();
The correct JSON for your code would look like this:
{
"Property1": [{
"copyright": "Jeff DaiTWAN",
"date": "2022-03-01",
"url": "https://apod.nasa.gov/apod/image/2203/DuelingBands_Dai_960.jpg"
}]
}

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.

Newtonsoft.Json Custom Root Name for Deserialization

I have this class that defines the json format:
public class ResultType
{
public bool status { get; set; }
public string message { get; set; }
}
The actual json looks like this:
{"result":{"status":true,"message":"Success"}}
How can I override the root attribute when de-serializing the json to "result"
JObject jsonResponse = JObject.Parse(jsonString);
ResultType _Data = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultType>(jsonResponse["result"].ToString());
Console.WriteLine(_Data.status);
Fiddle: https://dotnetfiddle.net/gjYS2p
I have a central deserialization method, so I'm trying to avoid type specific code as much as possible.
I used the following to resolve the problem, maybe not as sexy as I was hoping for but it works.
public class ResultType
{
public ResultDetailType result { get; set; }
}
public class ResultDetailType
{
public bool status { get; set; }
public string message { get; set; }
}

Convert JSON to C# type

i would like use uknown object from JS like this
{"aa":{"abcd
1":{"uio":[],"uio2":[],"uio3":["opee1","opee2","opee3"]},"abcd
2":null,"abcd 3":null,"abcd 4":null}}
sent into MVC with contentType 'application/json'. This object has no permament keys, like this name "abcd 1" can be another name in future.
i have function Test(Object aa) and question is, what type i must use for unknown array of objects or strings. Thanks
Have you tried this website before: http://json2csharp.com/ ?
Though the ASP.NET 4.0 built in JSON to C# parsing/serialization works great and in most cases you can just define a simple C# class that models the "signature" of your JSON and get the correct C# representation of your JSON with a call to something like Test(MyCSharpJsonObj aa), you seem to need something more robust. Note with the code you are about to see below, don't think you can overload your functions like so Test(ListData1 aa), Test(ListData2 aa), ASP.NET won't correctly call the right function for you on request from client and may not even compile correctly, if using Web API, not sure.
You more likely will have to call the right function from the client who is intimate with the JSON being sent in the request like so: Test1(ListData1 aa), Test2(ListData2 aa) using the code like below to assist you:
[Serializable]
[DataContract]
public class ListData1
{
[DataMember]
public string r0 { get; set; }
[DataMember]
public string r1 { get; set; }
[DataMember]
public string r2 { get; set; }
[DataMember]
public List<Data1> optdata { get; set; }
public ListData1() { }
public string ToJson()
{
return JSONHelper.Serialize<ListData1>(this);
}
}
[Serializable]
[DataContract]
public class Data1
{
[DataMember]
public string label { get; set; }
[DataMember]
public string d0 { get; set; }
[DataMember]
public string d1 { get; set; }
public Data1() { }
public string ToJSON()
{
return JSONHelper.Serialize<Data1>(this);
}
}
[Serializable]
[DataContract]
public class ListData2
{
[DataMember]
public string r0 { get; set; }
[DataMember]
public string r1 { get; set; }
[DataMember]
public string r2 { get; set; }
[DataMember]
public List<Data2> optdata { get; set; }
public ListData2() { }
public string ToJson()
{
return JSONHelper.Serialize<ListData2>(this);
}
}
[Serializable]
[DataContract]
public class Data2
{
[DataMember]
public string label { get; set; }
[DataMember]
public string d0 { get; set; }
[DataMember]
public string d1 { get; set; }
[DataMember]
public string d2 { get; set; }
public Data2() { }
public string ToJSON()
{
return JSONHelper.Serialize<Data2>(this);
}
}
public static class JSONHelper
{
public static string Serialize<T>(T obj)
{
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, obj);
string retVal = Encoding.UTF8.GetString(ms.ToArray());
return retVal;
}
public static T Deserialize<T>(string json)
{
if (string.IsNullOrEmpty(json))
{
return default(T);
}
T obj = Activator.CreateInstance<T>();
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms);
ms.Close();
return obj;
}
}
For my personal experience, the most useful way to consume Json inside a code is to use dynamics. Basically, instead of serializing/deserializing to specific type, you convert json object to dynamic one.
In this case you loose compile time validation, but get ability to support of any document structure.
In MVC4 you may use build-in Json.Decode() method from System.Web.Helpers.dll which will return you dynamic object. Otherwise, there are lots of libraries for that specific purpose, like Json.Net
Finally I found solution. Use Newtonsoft.Json and this code as sample for dynamic data structure:
$.ajax({
...
data: {data: JSON.stringify({first: "name", next: ["a", "b"], last: {o: "in"}})}
})
[HttpPost]
public JsonResult SaveMenu(String data)
{
dynamic JData = JObject.Parse(data);
//--now JData.first == "name"
if (JData.last is JObject)
{
}
//--or dynamic foreach
foreach (dynamic own in JData)
{
//--own.Name == first, next and last
//--access to variable == JData[own.Name]
if (JData[own.Name] is JArray)
{
foreach (String var in JData[own.Name])
{
}
}
}
}

Categories