Im trying to parse an JSON response string to my class objects.. I can't figure this out and i need some help with this.
I use the json.net reference but i cant't find what i'm looking for :(
my json:
{
"#companyName": "Company Name",
"#version": "1.0",
"#generatedDate": "3/1/10 2:10 PM",
"application": [
{
"#name": "Application #1 name",
"#apiKey": "1234",
"#createdDate": "2010-03-01",
"#platform": "Platform name"
},
{
"#name": "Application #1 name",
"#apiKey": "1234",
"#createdDate": "2010-03-01",
"#platform": "Platform name"
}
]
}
my root class for the json is:
public class RootObject
{
[JsonProperty]
public string companyName { get; set; }
[JsonProperty]
public string version { get; set; }
[JsonProperty]
public string generatedDate { get; set; }
[JsonProperty]
public List<Application> application { get; set; }
}
my sub class (list of applications):
public class Application
{
[JsonProperty]
public string name { get; set; }
[JsonProperty]
public string apiKey { get; set; }
[JsonProperty]
public string createdDate { get; set; }
[JsonProperty]
public string platform { get; set; }
}
To parse it i have the following code now:
JObject obj = JObject.Parse(e.Result);
applications = new RootObject
{
companyName = (string) obj["companyName"],
version = (string) obj["version"],
generatedDate = (string) obj["generatedDate"],
application = ???????? (how to make a list here?)
}
Thanks in advance!
Change your class definitions as follows
public class RootObject
{
[JsonProperty("#companyName")]
public string companyName { get; set; }
[JsonProperty("#version")]
public string version { get; set; }
[JsonProperty("#generatedDate")]
public string generatedDate { get; set; }
public List<Application> application { get; set; }
}
public class Application
{
[JsonProperty("#name")]
public string name { get; set; }
[JsonProperty("#apiKey")]
public string apiKey { get; set; }
[JsonProperty("#createdDate")]
public string createdDate { get; set; }
[JsonProperty("#platform")]
public string platform { get; set; }
}
and deserialize
var rootObj = JsonConvert.DeserializeObject<RootObject>(myjson);
A project I work on occasionally uses Json.Net. It's a wonderful library.
I would use the JsonConvert.DeserializeObject method instead.
In your case I would try something like this:
var result = JsonConvert.DeserializeObject<RootObject>(yourJsonString);
That should take care of it.
Can you try the following code and report back any issues:
RootObject applications = JsonConvert.DeserializeObject<RootObject>(e.Result);
Related
I'm querying an external service and wanted to deserialize the response into a customer object but the issue is response for each customer may be different. some customer may have Sales entity in the response and few may have Marketing.
The json property for sales entity is SalesId and for marketing is MarketingId. Can you advise whether the model I use to store result is correct or any improvement ? If so, how would I deserialize the response without knowing the correct json property ?
For Customer 66666
{
"customerId": "66666",
"customerName": "test1234",
"dependentEntity": [
{
"SalesId": "3433434",
"SalesPersonName": "343434",
"SaleSource": "StorePurchase"
}
]
}
For Customer 5555
{
"customerId": "55555",
"customerName": "test2",
"dependentEntity": [
{
"MarketingId": "3433434",
"MarketingAppName": "343434",
"MarketingSource": "Online"
}
]
}
Here is the Model I'm thinking but not sure the correct one
public class Customer
{
public string customerId { get; set; }
public string customerName { get; set; }
public IList<T> dependentList { get; set; }
}
public class Dependent
{
[JsonProperty("Id")]
public string Id { get; set; }
public string Name { get; set; }
public string Source { get; set; }
}
You could probably try something like the following one:
public class DependentEntity
{
[JsonProperty("SalesId")]
public string SalesId { get; set; }
[JsonProperty("SalesPersonName")]
public string SalesPersonName { get; set; }
[JsonProperty("SaleSource")]
public string SaleSource { get; set; }
[JsonProperty("MarketingId")]
public string MarketingId { get; set; }
[JsonProperty("MarketingAppName")]
public string MarketingAppName { get; set; }
[JsonProperty("MarketingSource")]
public string MarketingSource { get; set; }
}
public class Customer
{
[JsonProperty("customerId")]
public string CustomerId { get; set; }
[JsonProperty("customerName")]
public string CustomerName { get; set; }
[JsonProperty("dependentEntity")]
public IList<DependentEntity> DependentEntity { get; set; }
}
We have a type for DependentEntity that has both the attributes of Marketing and Sales object. After parsing your input, you could create a logic (checking the attributes) based on which you could check if a DependentEntity is a Marketing or a Sales object.
The above classes was generated using, jsonutils.
If we can assume that the dependentEntity contains only a single type of objects then you can use json.net's schema to perform branching based on the matching schema.
So, lets suppose you have these dependent entity definitions:
public class DependentMarket
{
public string MarketingId { get; set; }
public string MarketingAppName { get; set; }
public string MarketingSource { get; set; }
}
public class DependentSales
{
public string SalesId { get; set; }
public string SalesPersonName { get; set; }
[JsonProperty("SaleSource")]
public string SalesSource { get; set; }
}
...
Then you can use these classes to generate json schemas dynamically:
private static JSchema marketSchema;
private static JSchema salesSchema;
//...
var generator = new JSchemaGenerator();
marketSchema = generator.Generate(typeof(DependentMarket));
salesSchema = generator.Generate(typeof(DependentSales));
And finally you can do the branching like this:
var json = "...";
var semiParsedJson = JObject.Parse(json);
JArray dependentEntities = (JArray)semiParsedJson["dependentEntity"];
JObject probeEntity = (JObject)dependentEntities.First();
if (probeEntity.IsValid(marketSchema))
{
var marketEntities = dependentEntities.ToObject<List<DependentMarket>>();
...
}
else if (probeEntity.IsValid(salesSchema))
{
var salesEntities = dependentEntities.ToObject<List<DependentSales>>();
...
}
else if ...
else
{
throw new NotSupportedException("The provided json format is not supported");
}
I'm trying to deserialize JSON without declaring every property in C#. Here is a cut-down extract of the JSON:
{
"resourceType": "export",
"type": "search",
"total": 50,
"timestamp": "2020-08-02T18:26:06.747+00:00",
"entry": [
{
"url": "test.com/123",
"resource": {
"resourceType": "Slot",
"id": [
"123"
],
"schedule": {
"reference": {
"value": "testvalue"
}
},
"status": "free",
"start": "2020-08-03T08:30+01:00",
"end": "2020-08-03T09:00+01:00"
}
}
]
}
I want to get the values out of entry → resource, id and start.
Any suggestions on the best way to do this?
I've made very good experiences with json2sharp. You can enter your JSON data there and it will generate the classes you need to deserialize the JSON data for you.
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
public class Root
{
public string resourceType { get; set; }
public string type { get; set; }
public int total { get; set; }
public DateTime timestamp { get; set; }
public List<Entry> entry { get; set; }
}
The next step is to choose a framework which will help you to deserialize. Something like Newtonsoft JSON.
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
If you want to get the data without declaring classes, you can use Json.Net's LINQ-to-JSON API (JToken, JObject, etc.). You can use the SelectToken method with a JsonPath expression to get what you are looking for in a couple of lines. Note that .. is the recursive descent operator.
JObject obj = JObject.Parse(json);
List<string> ids = obj.SelectToken("..resource.id").ToObject<List<string>>();
DateTimeOffset start = obj.SelectToken("..resource.start").ToObject<DateTimeOffset>();
Working demo here: https://dotnetfiddle.net/jhBzl4
If it turns out there are actually multiple entries and you want to get the id and start values for all of them, you can use a query like this:
JObject obj = JObject.Parse(json);
var items = obj["entry"]
.Children<JObject>()
.Select(o => new
{
ids = o.SelectToken("resource.id").ToObject<List<string>>(),
start = o.SelectToken("resource.start").ToObject<DateTimeOffset>()
})
.ToList();
Demo: https://dotnetfiddle.net/Qe8NB7
I am not sure why you don't deserialize the lot (even if it's minimally populated) since you have to do the inner classes anyway.
Here is how you could bypass some of the classes (1) by digging into the JObjects
Given
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
You could call
var results = JObject.Parse(input)["entry"]
.Select(x => x.ToObject<Entry>());
I have a task to fetch the list of all missing updates using a C# .NET Framwork 4.7.2 windows Service which runs at specific intervals.
I have gotten this far to Fetch the Missing updates following this Answer.
Now I need to Put all the Fetched data in a JSON file using the following Format:
{
"hostName": "LRD-SomeHost",
"ip" : "192.168.13.12",
"mac" : "MAC:23:23:123:AS"
"timeStamp" : "CURRENT_TIME_STAMP",
"updates" : [
{
"updateID": "b32e464f-2e4a-4109-9018-33583a079a8a",
"updateDetails": [
{
"patchDescription" : "Some Long Description",
"patchCategory" : "28bc880e-0592-4cbf-8f95-c79b17911d5f"
"patchType" : "UpdateClassification"
"patchName" : "Update Rollups"
},
{
"patchDescription" : "Windows 10"
"patchCategory" : "a3c2375d-0c8a-42f9-bce0-28333e198407"
"patchType" : "Product"
"patchName" : "Windows 10"
},
{
"patchDescription" : "Windows 10 LTSB"
"patchCategory" : "d2085b71-5f1f-43a9-880d-ed159016d5c6"
"patchType" : "Product"
"patchName" : "Windows 10 LTSB"
}
]
}
]
}
Following is my C# Model:
namespace UpdateCollector
{
public class Host
{
public string hostname { get; set; }
public string ip { get; set; }
public string mac { get; set; }
public DateTime? timeStamp { get; set; }
public List<Updates> updates { get; set; }
}
public class Updates
{
public string updateID { get; set; }
public List<UpdateDetails> updateDetails { get; set; }
}
public class UpdateDetails
{
public string patchDescription { get; set; }
public string patchCategory { get; set; }
public string patchType { get; set; }
public string patchName { get; set; }
}
}
My Question is How to put my C# Data in this Format?
Thanks
You could use Json.NET to achieve this, here is a possible implementation:
First you need to install the package using NuGet:
Install-Package Newtonsoft.Json -Version 12.0.3
Then you define your classes in the same way you are doing, you can, however, use C# naming conventions and make use of attributes to specify different names for serialization:
public class Host
{
[JsonProperty(PropertyName = "hostname")]
public string Hostname { get; set; }
[JsonProperty(PropertyName = "ip")]
public string Ip { get; set; }
[JsonProperty(PropertyName = "mac")]
public string Mac { get; set; }
[JsonProperty(PropertyName = "timeStamp")]
public DateTime? TimeStamp { get; set; }
[JsonProperty(PropertyName = "updates")]
public List<Updates> Updates { get; set; }
}
public class Updates
{
[JsonProperty(PropertyName = "updateID")]
public string UpdateId { get; set; }
[JsonProperty(PropertyName = "updateDetails")]
public List<UpdateDetails> UpdateDetails { get; set; }
}
public class UpdateDetails
{
[JsonProperty(PropertyName = "patchDescription")]
public string PatchDescription { get; set; }
[JsonProperty(PropertyName = "patchCategory")]
public string PatchCategory { get; set; }
[JsonProperty(PropertyName = "patchType")]
public string PatchType { get; set; }
[JsonProperty(PropertyName = "patchName")]
public string PatchName { get; set; }
}
To serialize your class to json you can use the following statement:
var host = new Host();
// Fill all the properties, lists etc...
string json = JsonConvert.SerializeObject(host, Formatting.Indented);
To deserialize a json string back to the a C# object you use the opposite statement:
Host host = JsonConvert.DeserializeObject<Host>(json);
The code above should work for most cases but if you need to serialize / deserialize any of your objects in a special way you can write a custom JsonConverter: see here for an example.
Install Newtonsoft.Json package and do serialization of your object.
follow below code example.
List<Host> dataList=new List<Host>();
string jsonString = JsonConvert.SerializeObject(dataList);
I am working with opentdb.com api and have no idea how to access data in this json:
{
"response_code":0,
"results": [
{
"category":"Animals",
"type":"multiple",
"difficulty":"easy",
"question":"What is the scientific name for modern day humans?",
"correct_answer":"Homo Sapiens",
"incorrect_answers":[
"Homo Ergaster",
"Homo Erectus",
"Homo Neanderthalensis"
]
},
{
"category":"Entertainment: Cartoon & Animations",
"type":"multiple",
"difficulty":"easy",
"question":"Who voices for Ruby in the animated series RWBY?",
"correct_answer":"Lindsay Jones",
"incorrect_answers":[
"Tara Strong",
"Jessica Nigri",
"Hayden Panettiere"
]
}
]
}
I am using Newtonsoft.Json and i tried this with only 1 Question but im geting an error that says that key value is wrong..
class Trivia
{
public Trivia(string json)
{
JObject jObject = JObject.Parse(json);
JToken jresults = jObject["results"];
category = (string)jresults["category"];
type = (string)jresults["type"];
difficulty = (string)jresults["difficulty"];
question = (string)jresults["question"];
correct_answer = (string)jresults["correct_answer"];
incorrect_answers = jresults["incorrect_answers"].ToArray();
}
public string category { get; set; }
public string type { get; set; }
public string difficulty { get; set; }
public string question { get; set; }
public string correct_answer { get; set; }
public Array incorrect_answers { get; set; }
}
Copy from json text and in new class in visual studio Edit-->Paste Special-->Paste JSON As Classes
public class Rootobject
{
public int response_code { get; set; }
public Result[] results { get; set; }
}
public class Result
{
public string category { get; set; }
public string type { get; set; }
public string difficulty { get; set; }
public string question { get; set; }
public string correct_answer { get; set; }
public string[] incorrect_answers { get; set; }
}
using namespace
using Newtonsoft.Json;
response is value get from your service
var outdeserialized = JsonConvert.DeserializeObject<Rootobject>(response);
I've been trying create c# classes to map to a JSON format required by a service. But failing to find the right answer.
Here is the JSON:
{
"request": {
"path": "1",
"coverages": {
"path": "2",
"broadcastCoverage": {
"path": "3",
"name": "First Coverage",
"channel": "Channel 9",
"callSign": "DSOTM"
},
"internetCoverage": {
"path": "4",
"name": "Second Coverage",
"url": "www.stackoverflow.com"
},
"thirdCoverage": {
"path": "5",
"name": "Third Coverage",
"differentProperty": "Units"
}
}
}
}
If I put this into a JSON to C# converter I get the following:
public class BroadcastCoverage
{
public string path { get; set; }
public string name { get; set; }
public string channel { get; set; }
public string callSign { get; set; }
}
public class InternetCoverage
{
public string path { get; set; }
public string name { get; set; }
public string url { get; set; }
}
public class ThirdCoverage
{
public string path { get; set; }
public string name { get; set; }
public string differentProperty { get; set; }
}
public class Coverages
{
public string path { get; set; }
public BroadcastCoverage broadcastCoverage { get; set; }
public InternetCoverage internetCoverage { get; set; }
public ThirdCoverage thirdCoverage { get; set; }
}
public class Request
{
public string path { get; set; }
public Coverages coverages { get; set; }
}
public class RootObject
{
public Request request { get; set; }
}
But I need different types of Coverages (Broadcast, Internet, others) to be variable so I tried taking those out of the Coverages class and added a property:
public Dictionary<string, CoverageBase> CoverageList { get; set; }
Which will allow me to choose which coverages to include, the problem then becomes the CoverageList property name is in the JSON when it is serialized. I essentially would like a key/value (string, CoverageBase) without the property name.
Is there a way to add key value pairs without having the property name in the JSON? I've seen examples where this is done at the root object level but I haven't been able to find any example where it nested within the JSON.
If this can't be done with a simple object model what would be a recommended method to get the JSON built?
UPDATE: I like the answer that utilizes JsonSubTypes as it doesn't require much code, however I can't use a 3rd party library outside of json.net. Is there a way to accomplish this using a JsonConverter?
I think its possible as checked here, however it seems your app needs to reconstruct the json in a format where it includes the C# typings. More documentation here.
EDIT:
Thanks to dbc's reference I was able to dive in to the JsonSubtypes and its pretty easy to implement.
Here's my code base structure.
[JsonConverter(typeof(JsonSubtypes))]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(BroadcastCoverage), "channel")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(InternetCoverage), "url")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(ThirdCoverage), "differentProperty")]
public class CoverageBase
{
public string path { get; set; }
public string name { get; set; }
}
public class BroadcastCoverage : CoverageBase
{
public string channel { get; set; }
public string callSign { get; set; }
}
public class InternetCoverage : CoverageBase
{
public string url { get; set; }
}
public class ThirdCoverage : CoverageBase
{
public string differentProperty { get; set; }
}
public class Request
{
public string path { get; set; }
public List<CoverageBase> coverages { get; set; }
}
However the Json you're receiving was not quite ideally structured, so I did some reformatting just to let it to be properly parsed.
string json = "{\"request\":{\"path\":\"1\",\"coverages\":{\"path\":\"2\",\"broadcastCoverage\":{\"path\":\"3\",\"name\":\"First Coverage\",\"channel\":\"Channel 9\",\"callSign\":\"DSOTM\"},\"internetCoverage\":{\"path\":\"4\",\"name\":\"Second Coverage\",\"url\":\"www.stackoverflow.com\"},\"thirdCoverage\":{\"path\":\"5\",\"name\":\"Third Coverage\",\"differentProperty\":\"Units\"}}}}";
var jsonReq = JObject.Parse(json);
var pathVal = jsonReq["request"]["path"].Value<string>();
var coverageObjects = jsonReq["request"]["coverages"].Value<JObject>();
var filteredObjects = coverageObjects.Children().Where(x => x.Value<JProperty>().Name.EndsWith("Coverage"));
var dictionary = filteredObjects.Select(x => new KeyValuePair<string, string>(x.Value<JProperty>().Name, x.Value<JProperty>().Value.ToString()));
// reformatted Json
var newJson = "{ \"path\":\"" + pathVal + "\", \"coverages\" : [" + String.Join(",", dictionary.Select(x => x.Value).ToList()) + "]}";
Request reqC = JsonConvert.DeserializeObject<Request>(newJson);