I have built a service that is retrieving a sample file.
return await _httpClient.GetFromJsonAsync<BitcoinDetails>("https://localhost:44356/sample-data/jsonresult.json");
Example
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"slug": "bitcoin",
"num_market_pairs": 9550,
"date_added": "2013-04-28T00:00:00.000Z",
"tags": [
"mineable",
"pow",
"sha-256",
"store-of-value",
"state-channels"
],
"max_supply": 21000000, -- or null if not set
"circulating_supply": 18555956,
"total_supply": 18555956,
"platform": null,
"cmc_rank": 1,
"last_updated": "2020-11-27T21:22:02.000Z",
"quote": {
"USD": {
"price": 17069.598651577406,
"volume_24h": 38571181876.87967,
"percent_change_1h": 1.46329039,
"percent_change_24h": 0.92405679,
"percent_change_7d": -8.25816318,
"market_cap": 316742721516.32965,
"last_updated": "2020-11-27T21:22:02.000Z"
}
}
}
Now I have a class that has the following properties
public class Datum
{
public int id { get; set; }
public string name { get; set; }
public string symbol { get; set; }
public string slug { get; set; }
public int num_market_pairs { get; set; }
public DateTime date_added { get; set; }
public List<string> tags { get; set; }
public long? max_supply { get; set; }
public double circulating_supply { get; set; }
public double total_supply { get; set; }
public Platform platform { get; set; }
public int cmc_rank { get; set; }
public DateTime last_updated { get; set; }
public Quote quote { get; set; }
}
Keeping in mind that there are many more records I am getting the following error
Unhandled exception rendering component: The JSON value could not be converted to System.Nullable`1[System.Int64]. Path: $.data[80].max_supply |
make dto nullable and then try as follows:
var response = client.GetAsync(apiUrl);
if (response.Result.IsSuccessStatusCode)
{
var data = response.Result.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<Datum>(data.Result);
return result;
}
I ended up using a proxy call however this code did work:
var response = await _httpClient.GetAsync("https://localhost:5001/proxy");
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<BitcoinDetails>(data);
return result;
}
else
{
throw new Exception("Failed to get data");
}
and added this to the class property
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
Related
I want to convert the following json string to a C# class. But i cant figure it out... even with a online converter programm like "json2csharp".
{[
{
"tmcp_post_fields": [],
"product_id": 703,
"per_product_pricing": true,
"cpf_product_price": "45",
"variation_id": false,
"form_prefix": "",
"tc_added_in_currency": "EUR",
"tc_default_currency": "EUR"
}
]}
Can someone help me?
I tried these false variations:
public class myclass
{
public List<object> tmcp_post_fields { get; set; }
public int product_id { get; set; }
public bool per_product_pricing { get; set; }
public string cpf_product_price { get; set; }
public bool variation_id { get; set; }
public string form_prefix { get; set; }
public string tc_added_in_currency { get; set; }
public string tc_default_currency { get; set; }
}
or a List of this class
List<myclass>
I use this code to convert it
if (value != null && value.GetType().FullName.StartsWith("Newtonsoft.Json"))
{
string s = value.GetType().FullName;
if (value.GetType().FullName.EndsWith("JArray"))
{
JArray ja = (JArray)Convert.ChangeType(value, typeof(JArray));
if (ja.HasValues)
{
try
{
return ja.ToObject<myclass>(); //this
return ja.ToObject<List<myclass>>(); //or this does NOT work for me
}
catch { }
return value;
}
else
return null;
}
I allway got this error:
Newtonsoft.Json.JsonReaderException - Error reading string. Unexpected
token
If I remove the first opening and closing {} it would work.
your json is not valid, it has extra {} on the sides. Try this
var json=...your json
json=json.Substring(1,json.Length-2);
var jsonDeserialized = JsonConvert.DeserializeObject<Data[]>(json);
and class
public class Data
{
public List<object> tmcp_post_fields { get; set; }
public int product_id { get; set; }
public bool per_product_pricing { get; set; }
public string cpf_product_price { get; set; }
public bool variation_id { get; set; }
public string form_prefix { get; set; }
public string tc_added_in_currency { get; set; }
public string tc_default_currency { get; set; }
}
Another option is to use insert string. This option is even better since you can use parse json string as well.
json=json.Insert(1,"result:");
var jsonDeserialized = JsonConvert.DeserializeObject<Root>(json);
and class
public class Root
{
public Data[] result {get; set;}
}
output
{
"result": [
{
"tmcp_post_fields": [],
"product_id": 703,
"per_product_pricing": true,
"cpf_product_price": "45",
"variation_id": false,
"form_prefix": "",
"tc_added_in_currency": "EUR",
"tc_default_currency": "EUR"
}
]
}
After using HttpClient class to convert my JSON to a string and deserialize it with
var response = Res.Content.ReadAsStringAsync().Result;
data = JsonConvert.DeserializeObject<List<Employee>>(response);
How do I pass the data that I receive in the Controller from the call using the Model below to the View?
public class RuleType
{
public int Id { get; set; }
public string Description { get; set; }
public bool Inactive { get; set; }
}
public class RuleCategory
{
public int Id { get; set; }
public string Description { get; set; }
public bool Inactive { get; set; }
}
public class Employee
{
public string Description { get; set; }
public object EndDateTime { get; set; }
public int Id { get; set; }
public bool Inactive { get; set; }
public int RuleAction { get; set; }
public DateTime StartDateTime { get; set; }
public RuleType RuleType { get; set; }
public RuleCategory RuleCategory { get; set; }
}
Here is one object from the call
[
{
"Description": "Test Description",
"EndDateTime": null,
"Id": 1,
"Inactive": false,
"RuleAction": -2,
"StartDateTime": "2017-01-06T14:58:58Z",
"RuleType": {
"Id": 6,
"Description": "Test Description",
"Inactive": false
},
"RuleCategory": {
"Id": 1,
"Description": "Description",
"Inactive": false
}
}
]
Not sure if I'm missing something, but if you have an object you want to return to the view from the controller, you simply:
return View(viewModel); // in your case viewModel = 'data'
As others have said here already, you should be deserializing the JSON into a RootObject instead of an Employee like so:
var response = Res.Content.ReadAsStringAsync().Result;
var data = JsonConvert.DeserializeObject<List<RootObject>>(response);
You can then pass the model into the view using just:
return View(data)
You should also consider renaming RootObject into something more useful (such as employee?) as RootObject is not a very useful or descriptive name.
public List<Movie> getPopularMovies()
{
List<Movie> movies = null;
var client = new HttpClient();
var task = client.GetAsync(url)
.ContinueWith((taskwithresponse) =>
{
var response = taskwithresponse.Result;
var jsonString = response.Content.ReadAsStringAsync();
jsonString.Wait();
movies = JsonConvert.DeserializeObject<List<Movie>>(jsonString.Result);
});
task.Wait();
return movies;
}
Json to convert
{
"page": 1,
"results": [
{
"poster_path": "/xfWac8MTYDxujaxgPVcRD9yZaul.jpg",
"adult": false,
"overview": "After his career is destroyed, a brilliant but arrogant surgeon gets a new lease on life when a sorcerer takes him under his wing and trains him to defend the world against evil.",
"release_date": "2016-10-25",
"genre_ids": [
28,
12,
14,
878
],
"id": 284052,
"original_title": "Doctor Strange",
"original_language": "en",
"title": "Doctor Strange",
"backdrop_path": "/hETu6AxKsWAS42tw8eXgLUgn4Lo.jpg",
"popularity": 55.113822,
"vote_count": 598,
"video": false,
"vote_average": 6.99
}
],
"total_results": 19676,
"total_pages": 984
}
I'd like to set movies as results array. My solution (what I found here) is about setting movies as the whole json (pagem results, total_results, total_pages). In fact the json answer is a single object.
How to get deeply inside this json (while converting) to set the List<Movie> movies to results array?
Create a class for the entire response, with a list of movies on it.
response = JsonConvert.DeserializeObject<JsonResponse>(jsonString.Result);
movies = response.Movies;
Example classes:
public class JsonResponse {
[JsonProperty("results")]
public List<Movie> Movies { get; set; }
[JsonProperty("page")]
public int Page { get; set; }
[JsonProperty("total_results")]
public int TotalResults { get; set; }
[JsonProperty("total_pages")]
public int TotalPages { get; set; }
}
public class Movie
{
[JsonProperty("poster_path")]
public string PosterPath { get; set; }
[JsonProperty("adult")]
public bool Adule { get; set; }
[JsonProperty("overview")]
public string Overview { get; set; }
[JsonProperty("release_date")]
public string ReleaseDate { get; set; }
[JsonProperty("genre_ids")]
public List<int> GenreIds { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("original_title")]
public string OriginalTitle { get; set; }
[JsonProperty("original_language")]
public string OriginalLanguage { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("backdrop_path")]
public string BackdropPath { get; set; }
[JsonProperty("popularity")]
public double Popularity { get; set; }
[JsonProperty("vote_count")]
public int VoteCount { get; set; }
[JsonProperty("video")]
public bool Video { get; set; }
[JsonProperty("vote_average")]
public double VoteAverage { get; set; }
}
We have to do some changes in existing JSON response and it requires to modify existing c# code too. Till now I've tried but don't get the exact idea about the formatting as it is new for me.
Can any one please check and suggest the changes in below code?
Existing JSON message:
"hotel_room_types": {
"QUEEN": {
"code": "QUEEN",
"bed_type": {
"standard": [
5
],
"custom": []
},
"extra_bed_type": {
"standard": [
5
],
"custom": []
},
"accessibility": "compliant_with_local_laws_for_disabled",
"room_smoking_policy": "non_smoking"
}
}
In above JSON message we have to replace the "bed_type" and "extra_bed_type" with "bed_configurations" and "extra_bed_configurations" in below newly provided format by client:
"hotel_room_types": {
"QUEEN": {
"code": "QUEEN",
"bed_configurations": [
[{
"type": "standard",
"code": 3,
"count": 1
}],
[{
"type": "standard",
"code": 1,
"count": 2
}]
],
"extra_bed_configurations": [
[{
"type": "standard",
"code": 900302,
"count": 1
},
{
"type": "custom",
"name": "Rollaway with wheel locks and adjustable height",
"count": 1
}]
],
"accessibility": "compliant_with_local_laws_for_disabled",
"room_smoking_policy": "non_smoking"
}
}
Existing C# code to generate the JSON response message format:
public class HotelRoomType
{
public string code { get; set; }
public string name { get; set; }
public string description { get; set; }
public List<Photo> photos { get; set; }
public Amenities room_amenities { get; set; }
public string room_size { get; set; }
public string room_size_units { get; set; }
public BedType bed_type { get; set; }
public BedType extra_bed_type { get; set; }
public RoomViewType room_view_type { get; set; }
public string accessibility { get; set; }
public MaxOccupancy max_occupancy { get; set; }
public string room_smoking_policy { get; set; }
}
Below is the code to fill the data in required fields of JSON message its inside a method which contains lines of code so I get it separately:
HotelRoomType hotelrmtype = new HotelRoomType();
hotelrmtype.bed_type = Common.GetStandardBedTypeMappingID(rm.BedType);
if (rm.NumOfBed > 1)
hotelrmtype.extra_bed_type = hotelrmtype.bed_type; //same as bed type
hotelrmtypeDict.Add(rm.Code, hotelrmtype); //Binding Data into Dictionary.
GetStandardBedTypeMappingID() contains :
public static CRS.TripConnect.BedType GetStandardBedTypeMappingID(short code)
{
CRS.TripConnect.BedType tripConnectBedType = new CRS.TripConnect.BedType();
List<int> standardBedTypes = new List<int>();
List<object> customBedTypes = new List<object>();
tripConnectBedType.standard = standardBedTypes;
tripConnectBedType.custom = customBedTypes; //These is blank.
short id = 0;
switch (code)
{
case 10:
id = 3;
break;
case 20: // 20 Queen Q 5
id = 5;
break;
case 30: // 30 Double D 1
id = 1;
break;
case 40: // 40 Twin T 8
id = 8;
break;
}
standardBedTypes.Add(id);
return tripConnectBedType;
}
Update: With the help of #Sam Answer below I have modified the code:
public class HotelRoomType
{
//Added following properties
public List<List<Bed_Configurations>> bed_configurations { get; set; }
public List<List<Extra_Bed_Configurations>> extra_bed_configurations { get; set; }
}
Created two new classes as:
public class Bed_Configurations
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
}
public class Extra_Bed_Configurations
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
public string name { get; set; }
}
Now the question is: How to fill these two list?
I'm trying to achieve this like below but it is giving me conversion error.
Bed_Configurations bdConfig = new Bed_Configurations();
bdConfig.type = "Standard";
bdConfig.code = Common.GetStandardBedTypeMappingIDnew(rm.BedType);
bdConfig.count = rm.NumOfBed;
hotelrmtype.bed_configurations.Add(bdConfig);
Error Message:
Please Advise the changes in the above code so as to get the required JSON message. Appreciate your help!
public class RootClass
{
public HotelRoomType hotel_room_types { get; set; }
}
public class HotelRoomType
{
public BedModelAndDetails QUEEN { get;set; }
}
public class BedModelAndDetails
{
public string accessibility { get; set; }
public string room_smoking_policy { get; set; }
public string code { get; set; }
//public BedType bed_type { get; set; }
public object bed_type { get; set; }
//public BedType extra_bed_type { get; set; }
public object extra_bed_type { get; set; }
public List<List<BedConfiguration>> bed_configurations { get; set; }
public List<List<BedConfiguration>> extra_bed_configurations { get; set; }
}
public class BedType
{
public List<int> standard { get; set; }
public List<int> custom { get; set; }
}
public class BedConfiguration
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
}
[TestMethod]
public void ReplaceJson()
{
var inputJson1 = "{\"hotel_room_types\": {\"QUEEN\": {\"code\": \"QUEEN\", \"bed_type\": {\"standard\": [5],\"custom\": [] }, \"extra_bed_type\": { \"standard\": [5], \"custom\": [] },\"accessibility\": \"compliant_with_local_laws_for_disabled\", \"room_smoking_policy\": \"non_smoking\" } " +"}}";
var input1 = JsonConvert.DeserializeObject<RootClass>(inputJson1, new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore});
var inputJson2 = "{\"hotel_room_types\": {\"QUEEN\": {\"code\": \"QUEEN\",\"bed_configurations\": [[{\"type\": \"standard\",\"code\": 3,\"count\": 1}],[{\"type\": \"standard\",\"code\": 1,\"count\": 2}]],\"extra_bed_configurations\": [[{\"type\": \"standard\",\"code\": 900302,\"count\": 1},{\"type\": \"custom\",\"name\": \"Rollaway with wheel locks and adjustable height\",\"count\": 1}]],\"accessibility\": \"compliant_with_local_laws_for_disabled\",\"room_smoking_policy\": \"non_smoking\"} }}";
var input2 = JsonConvert.DeserializeObject<RootClass>(inputJson2);
//var finalInput = new RootClass();
//finalInput.hotel_room_types = inputJson1
//input1.hotel_room_types.QUEEN.bed_configurations = input2.hotel_room_types.QUEEN.bed_configurations;
//input1.hotel_room_types.QUEEN.extra_bed_configurations = input2.hotel_room_types.QUEEN.extra_bed_configurations;
input1.hotel_room_types.QUEEN.bed_type = input2.hotel_room_types.QUEEN.bed_configurations;
input1.hotel_room_types.QUEEN.extra_bed_type = input2.hotel_room_types.QUEEN.extra_bed_configurations;
}
Does this help?
I have the following JSON that I need to parse :
{
"code": 200,
"status": "OK",
"response": {
"course_accessJSON": null,
"in_progress": 1,
"completed": 0,
"passed": 0,
"location": "http://*************************************",
"subscription": {
"started": 1465834293,
"expired": 1473869493,
"payment": "account"
},
"is_expired": false,
"course_progress": {
"CMP1044": {
"course_name_en": "Java Programming",
"no_of_lessons": 30,
"viewed": 1,
"viewed_start": 1465834789,
"viewed_end": null,
"cert_attemptsCSV": null,
"cert_resetsCSV": null,
"cert_serial": null,
"high_score": null,
"location": "http://***************************"
}
}
}
}
I have managed to get all the elements out except the value in the course_progress item using the following:
SampleResourse obj = JsonConvert.DeserializeObject<SampleResourse>(s);
Response.Write(obj.Response.CourseProgress.CMP1044.CourseNameEn.ToString());
class SampleResourse
{
[JsonProperty("code")]
public int respcode { get; set; }
[JsonProperty("status")]
public string respStatus { get; set; }
[JsonProperty("response")]
public Response2 Response { get; set; }
}
class Response2
{
[JsonProperty("in_progress")]
public int InProgress { get; set; }
[JsonProperty("completed")]
public int Completed { get; set; }
[JsonProperty("passed")]
public int Passed { get; set; }
[JsonProperty("course_progress")]
public CourseProgress CourseProgress { get; set; }
}
class CourseProgress
{
[JsonProperty("CMP1044")]
public CMP10442 CMP1044 { get; set; }
}
class CMP10442
{
[JsonProperty("course_name_en")]
public string CourseNameEn { get; set; }
}
I need the elements course_name_en, no_of_lessons,viewed however there will be multiple properties similar to "CMP1044". Each "CMP" property will have a unique number. I want to list progress on each.
Simply change the following :
class Response2
{
[JsonProperty("in_progress")]
public int InProgress { get; set; }
[JsonProperty("completed")]
public int Completed { get; set; }
[JsonProperty("passed")]
public int Passed { get; set; }
[JsonProperty("course_progress")]
public Dictionary<string, CourseProgress> CourseProgress { get; set; }
}
class CourseProgress
{
[JsonProperty("course_name_en")]
public string CourseNameEn { get; set; }
}
To list the course name along with the id, you can do this:
var resource = Newtonsoft.Json.JsonConvert.DeserializeObject<SampleResourse>(json);
foreach (var kvp in resource.Response.CourseProgress)
{
Response.Write(kvp.Key + ":" + kvp.Value.CourseNameEn + Environment.NewLine);
}