I do a request to a api that I'm using and this is the response that I get back.
{ "id": 1139, "performanceStatus": "OK", "availabilityStatus": "OK" }
I would like to convert this response in a list where I then can use a for/foreach loop and later can use linq and SelectMany to create a whole new list.
I got this far, but I am stuck the code is not hitting the var "newJson"..
Can someone help me out?
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
dynamic parsedJson = JObject.Parse(json);
foreach (var j in parsedJson)
{
j.Replace(JObject.FromObject(
new {
id = j.id,
performance = j.performanceStatus,
availability = j.availabilityStatus
}));
}
var newJson = parsedJson.ToString();
Later I would like to Deserialize it into a strongly typed class. Like so
boi = await Task.Run(() => JsonConvert.DeserializeObject<Boi>(newJson)).ConfigureAwait(false);
Here is the strongly typed class
public class Boi
{
public int Id { get; set; }
public string PerformanceStatus { get; set; }
public string AvailabilityStatus { get; set; }
}
public class NewBoi
{
public List<Boi> eeg { get; set; }
}
You could do this:
var jsn = "{ \"id\": 1139, \"performanceStatus\": \"OK\", \"availabilityStatus\": \"OK\" }";
var bois = new List<Boi> { JsonConvert.DeserializeObject<Boi>(jsn) };
var newBoi = new NewBoi() { eeg = bois };
Although I would question the need for the NewBoi class - you could just work with the List.
To deserialize to a well known type use
JsonConvert.Deserialize<T>(jsonString,new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
where T is your well known type.
Related
This is what my logic looks like:
public void SetVideoInfo(string videoID)
{
var url = new RestClient("https://www.googleapis.com/youtube/v3/videos?
part=snippet&fields=items(snippet(title,description))&id=" + videoID +
"&key=somekey");
url.Timeout = -1;
var urlRequest = new RestRequest(Method.GET);
var urlResponse = url.Execute(urlRequest);
var response = JObject.Parse(urlResponse.Content);
var data = (JArray)response["items"];
for (int i = 0; i < data.Count; i++)
{
var videoTitle = data[i]["title"];
var videoDescription = data[i]["description"];
this.VideoTitle = videoTitle.ToString().Trim();
this.VideoDescription = videoDescription.ToString().Trim();
}
}
This is what the API response looks like:
{
"items": [
{
"snippet": {
"title": "some title",
"description": "some description"
}
}
]
}
My current logic gets up to "snippet" but I get nulls for title and description. I just want to know how am I able to get to the title and description attributes.
RestSharp has methods for parsing results directly into proper C# classes, use them instead of messing around with JObjects and JArrays. Off the top of my head, something like this should work.
First, make some classes to hold your data:
public class Root
{
public List<Item> Items { get; set; }
}
public class Item
{
public Snippet Snippet { get; set; }
}
public class Snippet
{
public string Title { get; set; }
public string Description { get; set; }
}
Now call the generic method of RestSharp:
var urlResponse = url.Execute<Root>(urlRequest);
Now you can access the properties in a type-safe way.
var title = urlResponse.Items[0].Snippet.Title
var description = urlResponse.Items[0].Snippet.Description
My Web API (code that generates JSON) is generating the following JSON string. It seems, if I am not wrong, that it has been encoded twice:
"\"[{\\\"SportID\\\":1,\\\"SportName\\\":\"Tennis\\\"},{\"SportID\\\":2,\\\"SportName\\\":\\\"Footbal\\\"},{\"SportID\\\":3,\"SportName\":\\\"Swimming\\\"}]\""
Web API code:
public string JSONTest()
{
List<Sport> sports = new List<Sport>();
sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });
try
{
return JsonConvert.SerializeObject(sports);
}
catch (Exception ex) { }
}
Sport class:
public class Sport { public int SportID { get; set; } public string SportName { get; set; } }
Screenshot of getting JSON:
The following line gives me an error, I think because of twice encoding:
var JavaScriptSerializerResult = (new JavaScriptSerializer()).Deserialize< List<Sport>>(jsonResponse);
I get the same error if try with this:
var jsonConvertResult = JsonConvert.DeserializeObject<List<Sport>>(jsonResponse);
How can I fix my Web API to not encode twice, or if that is not the problem, how can I decode this JSON?
I think you should try JsonConvert.DeserializeObject to deserialize the JSON:
public class Sport
{
// Dummy "Sport" class as it was not mentioned by OP.
public int SportID { get; set; }
public string SportName { get; set; }
}
I get serialized JSON as:
Deserialized it:
string json = JSONTest();
var obj = JsonConvert.DeserializeObject<List<Sport>>(json);
Output:
UPDATE:
As per OP's shared JSON (which is being received from server), encoding can be removed by using:
private string RemoveEncoding(string encodedJson)
{
var sb = new StringBuilder(encodedJson);
sb.Replace("\\", string.Empty);
sb.Replace("\"[", "[");
sb.Replace("]\"", "]");
return sb.ToString();
}
Deserialize it by:
string js = "\"[{\\\"SportID\\\":1,\\\"SportName\\\":\"Tennis\\\"},{\"SportID\\\":2,\\\"SportName\\\":\\\"Footbal\\\"},{\"SportID\\\":3,\"SportName\":\\\"Swimming\\\"}]\"";
string res = RemoveEncoding(js);
var obj = JsonConvert.DeserializeObject<List<Sport>>(res);
Shorter sample for json.net library.
Here, entity is my serializable C# object. I use JsonConvert along with some formatting and specify to ignore reference looping to prevent circular referencing.
using Newtonsoft.Json;
var json = JsonConvert.SerializeObject (entity, Formatting.Indented,
new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
});
Use Linq Query Concept:
public string JSONTest()
{ List<Sport> sports = new List<Sport>();
sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });
var result_sports = (from row in sports
group row by new { row.SportID , row.SportName} into hdr
select new Sport()
{
SportID = hdr.Key.SportID ,
SportName = hdr.Key.SportName ,
}).ToList();
string jsondata = new JavaScriptSerializer().Serialize(result_sports);
}
Summary: Your return object is being serialized twice. Remove your hand-rolled serialization code and return objects from your web services - not JSON strings.
Your JSON is indeed being serialized 'twice'. Look closely at this screenshot and we see escaped quote marks:
Your list properly serialized should produce a JSON string something like this:
[{"SportID":1,"SportName":"Tennis"},{"SportID":2,"SportName":"Footbal"},{"SportID":3,"SportName":"Swimming"}]
But we have something more like this:
"[{\"SportID\":1,\"SportName\":\"Tennis\"},{\"SportID\":2,\"SportName\":\"Footbal\"},{\"SportID\":3,\"SportName\":\"Swimming\"}]"
I can replicate this (code below) and it means that your JSON string has itself been fed through a serializer.
This is almost certainly due to you manually serializing your List<Sport>. You don't need to do that. Web API serializes for you - hence the second run through a serializer.
Change the return type of your Web API function if necessary, and then instead of writing:
return JsonConvert.SerializeObject(sports);
just do
return sports;
Web API will take care of the serialization and you will no longer have the bothersome quotes and escape characters.
Code dump I tested with:
void Main()
{
string json = JSONTest();
Console.WriteLine(json);
var obj = JsonConvert.DeserializeObject<List<Sport>>(json);
string jsonX2 = JsonConvert.SerializeObject(json);
Console.WriteLine(jsonX2);
obj = JsonConvert.DeserializeObject<List<Sport>>(jsonX2); // exception
}
public string JSONTest()
{
List<Sport> sports = new List<Sport>();
sports.Add(new Sport() { SportID = 1, SportName = "Tennis" });
sports.Add(new Sport() { SportID = 2, SportName = "Footbal" });
sports.Add(new Sport() { SportID = 3, SportName = "Swimming" });
return JsonConvert.SerializeObject(sports);
}
public class Sport
{
public int SportID { get; set; }
public string SportName { get; set; }
}
Pretty silly question to ask. but could not figure it out .
In a C# MVC Controller action , I need to model a Json Array for testing purposes.
But this shows me compilation errors instead of being a valid Json:
var result = {
"controllerId": "controller1",
"controllerName": "ControllerOne"
};
But this is perfectly valid :
var scheduleResult = new[]
{
new { scheduleId = "schedule1",scheduleName = "scheduleOne"},
new { scheduleId = "schedule2",scheduleName = "scheduleTwo"}
};
Why so ?
Also how to write a nested Json array :
I tried :
var scheduleResult = new[]
{
new { scheduleId = "schedule1",scheduleName = "scheduleOne",new[]{ new {doorId="Door1",doorName="DoorOne"}, new { doorId = "Door2", doorName = "DoorTwo" } } },
new { scheduleId = "schedule2",scheduleName = "scheduleTwo"}
};
But it shows errors in syntax. What to do ?
I Need to have nested array within each element of that array .
Thanks in advance.
Well, C# does not support the way you wrote. You can't just type in JSON in C# and expect it to work unfortunately. You can try like that with anonymous type:
var result = new
{
controllerId = "controller1",
controllerName = "ControllerOne",
myArray = new []
{
"a",
"b"
}
};
This is converted to JSON no problem if you return it as a result of API call.
The nested arrays you are talking about don't work because you need to give them a name, you can't have array property without a name. See example above.
Why don't you use Dictionary<TKey, TValue> with Newtonsoft.Json?
Simple json:
IDictionary<string, string> obj = new Dictionary<string, string>();
obj.Add("controllerId", "controller1");
obj.Add("controllerName", "ControllerOne");
// {"controllerId":"controller1","controllerName":"ControllerOne"}
string json = JsonConvert.SerializeObject(obj);
Nested json:
IList<string> obj = new List<string>();
IDictionary<string, string> first = new Dictionary<string, string>();
first.Add("scheduleId ", "schedule1");
first.Add("scheduleName", "scheduleOne");
IDictionary<string, string> second = new Dictionary<string, string>();
second.Add("scheduleId ", "schedule2");
second.Add("scheduleName", "scheduleTwo");
string first_json = JsonConvert.SerializeObject(first);
string second_json = JsonConvert.SerializeObject(second);
obj.Add(first_json);
obj.Add(second_json);
// ["{\"scheduleId \":\"schedule1\",\"scheduleName\":\"scheduleOne\"}","{\"scheduleId \":\"schedule2\",\"scheduleName\":\"scheduleTwo\"}"]
string json = JsonConvert.SerializeObject(obj);
Here first of all we should create model class with the same pattern of our return type
public class ScheduleModel
{
public List<Schedule> ScheduleList { get; set; }
}
public class Schedule
{
public int ScheduleId { get; set; }
public string ScheduleName { get; set; }
public List<Door> DoorList { get; set; }
}
public class Door
{
public int DoorId { get; set; }
public string DoorName { get; set; }
}
Now at the controller Action create the test data
List<Door> doorList = new List<Door>();
doorList.Add(new Door{DoorId = "Door1",DoorName = "DoorOne"});
doorList.Add(new Door{DoorId = "Door2",DoorName = "DoorTwo"});
List<Schedule> scheduleList = new List<Schedule>();
scheduleList.Add(new Schedule{
ScheduleId = "schedule1",
ScheduleName = "scheduleOne",
DoorList = doorList
});
scheduleList.Add(new Schedule
{
ScheduleId = "schedule2",
ScheduleName = "scheduleTwo",
});
return Json(scheduleList, JsonRequestBehavior.AllowGet);
If this answer benefits you please mark as an answer.
I have the following JSON coming back from a remote API (I cannot modify the JSON returned)
{
"APITicket": {
"location": "SOMEVALUE",
"ticket": "SOMEVALUE"
}
}
Now using JSON.Net to convert to this to a model I have to create 2 models.
public class TicketModel
{
public string location { get; set; }
public string ticket { get; set; }
}
public class TicketContainer
{
public TicketModel APITicket { get; set; }
}
and do something like..
var myObject = JsonConvert.DeserializeObject<TicketContainer>(this.JSONResponse);
and this works well - my problem arises when I have around 50 calls to make to the API and really dont fancy creating a second 'Container' for each. Is there a way to bind the example above directly to the TicketModel?
You can do it this way:
var json = #"
{
'APITicket': {
'location': 'SOMEVALUE',
'ticket': 'SOMEVALUE'
}
}";
//Parse the JSON:
var jObject = JObject.Parse(json);
//Select the nested property (we expect only one):
var jProperty = (JProperty)jObject.Children().Single();
//Deserialize it's value to a TicketModel instance:
var ticket = jProperty.Value.ToObject<TicketModel>();
use Newtonsoft's JArray to customize ur json before deserialize
public List<APITicket> JsonParser(string json)
{
Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(json);
var list = new List<APITicket>();
foreach(var item in jArray)
{
list.Add(
new APITicket { location = item["APITicket"]["location"],
ticket = item["APITicket"]["ticket"]
}
);
}
return list;
}
Modify the JSON so it looks like this
{
"location": "SOMEVALUE",
"ticket": "SOMEVALUE"
}
and do
List<TicketModel> tickets = JsonConvert.DeserializeObject<List<TicketModel>>(this.JSONResponse);
or even
Dictionary<string, string> tickets = JsonConvert.DeserializeObject<Dictionary<string, string>>(this.JSONResponse);
so you don't need any models.
How can I deserialize:
{
"data": [
{"ForecastID":8587961,"StatusForecast":"Done"},
{"ForecastID":8588095,"StatusForecast":"Done"},
{"ForecastID":8588136,"StatusForecast":"Done"},
{"ForecastID":8588142,"StatusForecast":"Pending"}
]
}
to
class RawData
{
public string data { get; set; }
}
So, I just want to have
[
{"ForecastID":8587961,"StatusForecast":"Done"},
{"ForecastID":8588095,"StatusForecast":"Done"},
{"ForecastID":8588136,"StatusForecast":"Done"},
{"ForecastID":8588142,"StatusForecast":"Pending"}
]
as value of property data of RawData's class instance.
Using Json.Net
var obj = (JObject)JsonConvert.DeserializeObject(json);
var newJson = obj["data"].ToString();
or using built-in JavaScriptSerializer
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
var newjson = new JavaScriptSerializer().Serialize(dict["data"]);
It would have made far much more sense to deserialize this JSON structure to:
public class Forecast
{
public IEnumerable<ForecastData> Data { get; set; }
}
public class ForecastData
{
public int ForecastID { get; set; }
public string StatusForecast { get; set; }
}
which is pretty trivial with the JavaScriptSerializer class that's built into the framework:
string json = "your JSON data here";
IEnumerable<ForecastData> data = new JavaScriptSerializer()
.Deserialize<Forecast>(json)
.Data;
or if you don't want to define models you could do that:
dynamic result = new JavaScriptSerializer().DeserializeObject(json);
foreach (var item in result["data"])
{
Console.WriteLine("{0}: {1}", item["ForecastID"], item["StatusForecast"]);
}