What is a useful model which could bind a json object with arbitrary keys? Assume your json could look like:
{"##hello": "address","#world": "address1","name": "address"}
or
{"##hello": "address","#world": "address1","firstname": "foo", "lastname":"bar"}
or
{"##hello": "address","#world": "address1","children": [{"name":"foo"},{"name":"bar"}]}
So that means you only know at run time how the json model looks like. My current state is, that it seems the best practice is to send the json object as string to the controller and deserialize the json string it to an object.
public ActionResult mappingNodes(string model) {
dynamic json = Newtonsoft.Json.JsonConvert.DeserializeObject(model);
}
public class Children
{
[JsonProperty("name")]
public string Name { get; set; }
}
public class YourClass
{
[JsonProperty("##hello")]
public string Hello { get; set; }
[JsonProperty("#world")]
public string World { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("firstname")]
public string FirstName { get; set; }
[JsonProperty("lastname")]
public string LastName { get; set; }
[JsonProperty("children")]
public Children[] Children { get; set; }
}
var json1 = "{ '##hello': 'address','#world': 'address1','name': 'address'}";
var json2 = "{ '##hello': 'address','#world': 'address1','name': 'address', 'firstname': 'foo', 'lastname':'bar'}";
var json3 = "{ '##hello': 'address','#world': 'address1','name': 'address','children': [{'name':'foo'},{'name':'bar'}]}";
var model1 = JsonConvert.DeserializeObject<YourClass>(json1);
var model2 = JsonConvert.DeserializeObject<YourClass>(json2);
var model3 = JsonConvert.DeserializeObject<YourClass>(json3);
Related
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"
}]
}
i have this json string:
{"products": [{"id": 22,"date_add": "2021-06-17 19:21:26","date_upd": "2021-07-12 13:02:01","name": [{"id": "1","value": "Product 1"}, {"id": "2", "value": "Product 1"}]}}, {"id": 1,"date_add": "2021-06-17 18:54:54","date_upd": "2021-06-17 18:54:54","name": [{"id": "1","value": "something321"},{"id": "2","value": "something23"}]}]}
and this class:
class Products
{
[JsonProperty("id")]
public override string ExternalId { get; set; }
[JsonProperty("name")]
public Dictionary<string, string> Name { get; set; }
[JsonProperty("date_upd")]
public DateTime DateModified{ get; set; }
}
i want to map my json products to List of Products, so I tried this:
// get "products" array from json
Regex regex = new Regex(#"(?:{""products"":)(.+)(?:})");
MatchCollection matches = regex.Matches(result);
if (matches.Count > 0)
{
result = matches[0].Groups[1].Value;
}
else
{
result = null;
}
//
var deserialized = JsonConvert.DeserializeObject<List<PrestaProducts>>(result);
it throws: Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. ...
ok - if i set type of name to object, it works correct and set the list of anon objs.
( public object Name { get; set; } )
but how can i set that names to dictionary?
What I see from your example, you cannot convert name to Dictionary<string, string> since it's array.
However you can do something like this. Change this line to include List:
var deserialized = JsonConvert.DeserializeObject<List<Products>>(result);
and change your model to something like this:
public class Products
{
[JsonProperty("id")]
public string ExternalId { get; set; }
[JsonProperty("name")]
public List<Dictionary<string, string>> Name { get; set; }
[JsonProperty("date_upd")]
public DateTime DateModified { get; set; }
}
I don't know if this is what you expected or wanted but at least you will fix the error you have at the moment.
To me it does not make much sense to have dictionary inside list but you cannot directly convert array to dictionary in a way you tried.
You can convert it to list products
var jsonObj = JsonConvert.DeserializeObject<JsonObjects>(json);
var productObjects = jsonObj.products;
if you want to convert it to dictionary, try this:
var products = new Products { products = new List<Product> { } };
foreach (var item in productObjects)
{
var product = new Product
{
id = item.id,
date_add = item.date_add,
date_upd = item.date_upd,
name=new Dictionary<string,string>()
};
foreach (var name in item.name)
{
product.name.Add(name.id,name.value);
}
products.products.Add(product);
}
var productsJson= JsonConvert.SerializeObject( products);
OUTPUT
{"products":[
{"id":22,"date_add":"2021-06-17 19:21:26","date_upd":"2021-07-12 13:02:01",
"name":{"1":"Product 1","2":"Product 1"}},
{"id":1,"date_add":"2021-06-17 18:54:54","date_upd":"2021-06-17 18:54:54",
"name":{"1":"Hummingbird printed t-shirt","2":"Hummingbird printed t-shirt"}}
]}
classes
public class Name
{
public string id { get; set; }
public string value { get; set; }
}
public class JsonProduct
{
public int id { get; set; }
public string date_add { get; set; }
public string date_upd { get; set; }
public List<Name> name { get; set; }
}
public class JsonObjects
{
public List<JsonProduct> products { get; set; }
}
public class Product
{
public int id { get; set; }
public string date_add { get; set; }
public string date_upd { get; set; }
public Dictionary<string, string> name { get; set; }
}
public class Products
{
public List<Product> products { get; set; }
}
I have a Json that looks like this:
{
"Title:": "StructureTitle",
"Description:" : "StructureDescription",
"Contents": "[{"Key":"FirstKey","Value":"FirstValue"},{"Key":"SecondKey","Value":"SecondValue"},{"Key":"ThirdKey","Value":"ThirdValue"}]"
}
And I cannot figure out how to deserialize it because the Contents section is specifying what is the key and what is the value.
I've defined my classes this way
public class Info
{
public string Title{ get; set; }
public string Description{ get; set; }
public Contents Contents{ get; set; }
}
[DataContract]
public class Contents {
[DataMember(Name = "FirstKey")]
public string FirstKey{ get; set; }
[DataMember(Name = "SecondKey")]
public string SecondKey{ get; set; }
[DataMember(Name = "ThirdKey"]
public string ThirdKey { get; set; }
}
And I'm trying to perform the deserialization this way:
var text = "{ "Title:": "StructureTitle", "Description:" : "StructureDescription", "Contents": "[{"Key":"FirstKey","Value":"FirstValue"},{"Key":"SecondKey","Value":"SecondValue"},{"Key":"ThirdKey","Value":"ThirdValue"}]" }"
JToken token = JObject.Parse(text);
var x = token.SelectToken("Contents");
Contents c = x.ToObject<Contents>();
This is the error I'm getting:
Newtonsoft.Json.JsonSerializationException: 'Error converting value
var text = "{ \"Title: \": \"StructureTitle\", \"Description: \" : \"StructureDescription\", \"Contents\": [{ \"Key\":\"FirstKey\",\"Value\":\"FirstValue\"},{ \"Key\":\"SecondKey\",\"Value\":\"SecondValue\"},{ \"Key\":\"ThirdKey\",\"Value\":\"ThirdValue\"}] }";
JToken token = JObject.Parse(text);
var x = token.SelectToken("Contents");
Contents c = x.ToObject<Contents>();
I am new to C# need help to convert json Object to Array
convert this json
[
{
"Id": 1000,
"Name": "May",
"Address": "odyssey",
"Country": "USA",
"Phone": "12345"
}
]
To
var details = {1000,May,odyssey,USA,12345};
Use Newtonsoft.Json to deserialize JSON to a specified .net type. You can deserialize to a class too, see below:
public class Person
{
public int Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
public string Country {get;set;}
public string Phone {get;set;}
}
var details = JsonConvert.DeserializeObject<Person>(json);
You are going to have to deserialize the Json String. Deserialize into array of objects.
JavaScriptSerializer js = new JavaScriptSerializer();
yourClass[] items = js.Deserialize<Yourclass[]>(yourJSONcontent);
Steps:
1. Create Model.
2. Get Data in string
3.Deserialize Object
And if you are confused How to create C# model from the json then use this link.
https://app.quicktype.io
Use This Model.
public class Test
{
[JsonProperty("Id")]
public long Id { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("Address")]
public string Address { get; set; }
[JsonProperty("Country")]
public string Country { get; set; }
[JsonProperty("Phone")]
[JsonConverter(typeof(ParseStringConverter))]
public long Phone { get; set; }
}
string data="Your Json String"
var details = JsonConvert.DeserializeObject<Test>(data);
To make a list from your json values you can use a JObject, you don't have to know the objects stored in your Json in contrary to the others question.
JObject myObject = JsonConvert.DeserializeObject<JObject>(myJson);
List<object> myList = new List<object>();
foreach (var element in myObject)
{
myList.Add(element.Value);
}
If you already know what your json is made of, you can create a class that represent your object and implement the interface IEnumerable.
var myObject = JsonConvert.DeserializeObject<MyClass>(myJson);
var myArray = myObject2.ToArray():
public class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Country { get; set; }
public int Phone { get; set; }
public object[] ToArray()
{
return new object[]
{
Id,
Name,
Address,
Country,
Phone
};
}
}
NB : the variable myJson in the previous codes is a string that represent your json as var myJson = "{\"Id\": 1000,\"Name\": \"May\",\"Address\": \"odyssey\",\"Country\": \"USA\",\"Phone\": \"12345\"}";
My project has a 3rd party web API that returns a json string in the following format (including the starting and ending curly braces):
{
"866968030210604":{
"dt_server":"2019-02-07 12:21:27",
"dt_tracker":"2019-02-07 12:21:27",
"lat":"28.844968",
"lng":"76.858502",
"altitude":"0",
"angle":"154",
"speed":"9",
"params":{
"pump":"0",
"track":"1",
"bats":"1",
"acc":"0",
"batl":"4"
},
"loc_valid":"1"
},
"866968030221205":{
"dt_server":"2019-02-07 12:20:24",
"dt_tracker":"2019-02-07 12:19:41",
"lat":"28.845904",
"lng":"77.096063",
"altitude":"0",
"angle":"0",
"speed":"0",
"params":{
"pump":"0",
"track":"1",
"bats":"1",
"acc":"0",
"batl":"4"
},
"loc_valid":"1"
},
"866968030212030":{
"dt_server":"0000-00-00 00:00:00",
"dt_tracker":"0000-00-00 00:00:00",
"lat":"0",
"lng":"0",
"altitude":"0",
"angle":"0",
"speed":"0",
"params":null,
"loc_valid":"0"
}
}
I want to deserialize it into a c# class object for further processing. I made the following class structure for the same:
class Params
{
public string pump { get; set; }
public string track { get; set; }
public string bats { get; set; }
public string acc { get; set; }
public string batl { get; set; }
}
class GPSData
{
public string dt_server { get; set; }
public string dt_tracker { get; set; }
public string lat { get; set; }
public string lng { get; set; }
public string altitude { get; set; }
public string angle { get; set; }
public string speed { get; set; }
public Params ObjParams { get; set; }
public string loc_valid { get; set; }
}
and I am trying the following code to deserialize:
JavaScriptSerializer jSerObj = new JavaScriptSerializer();
List<GPSData> lstGPSData = (List<GPSData>)jSerObj.Deserialize(json, typeof(List<GPSData>));
But every time it is showing NULL values assigned to each property of the class after the Deserialize() method is called. Please help me on this.
Your json is not in list format so deserializing to List<> isn't work
So you need to deserialize it into Dictionary<string, GPSData> like
JavaScriptSerializer jSerObj = new JavaScriptSerializer();
Dictionary<string, GPSData> lstGPSData = (Dictionary<string, GPSData>)jSerObj.Deserialize(json, typeof(Dictionary<string, GPSData>));
Usage:
foreach (var item in lstGPSData)
{
string key = item.Key;
GPSData gPSData = item.Value;
}
Also, you can list all your GPSData from above dictionary like,
List<GPSData> gPSDatas = lstGPSData.Values.ToList();
Output: (From Debugger)