I have a simple JSON like this:
{
"id": 123,
"name": "BaseName",
"variation": { "name": "VariationName" }
}
Is there a simple way to map it with JSON.NET deserialization to:
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string VariationName { get; set; }
}
I can probably do it with a custom converter, but I hoped there would be a simpler way by annotating the class with attributes which would give instructions to deserialize the variation object just using the one property.
You could set up a class for variation and make VariationName a get-only property
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public Variation variation { get; set; }
public string VariationName { get { return variation.VariationName; } }
}
class variation
{
public string name { get; set; }
}
Related
I am fetching an API that returns a JSON response like this:
{
"id": 161635,
"rev": 1,
"fields": {
"System.Url": "http://google.com",
"System.Type": "Bug",
"System.State": "New",
"System.AssignedTo": {
"displayName": "John Doe"
}
}
}
I want to display the id and everything inside fields.
This is my model:
public class WorkItemDetail {
public int id { get; set; }
public Dictionary<string, object> fields {get;set;}
}
Here is the problem, I can display the id and everything in fields except for some reason, I can't show displayName
Here is what I doing:
#WorkItemDetailResponse.id
#WorkItemDetailResponse.fields["System.WorkItemType"];
#WorkItemDetailResponse.fields["System.State"];
#WorkItemDetailResponse.fields["System.AssignedTo"];
#WorkItemDetailResponse.fields["System.AssignedTo"]["displayName"]; <!-- does not work -->
#code{
WorkItemDetailResponse = JsonConvert.DeserializeObject<WorkItemDetail>(ResponseBody);
}
I am new to C# so I don't know why this line is not working
#WorkItemDetailResponse.fields["System.AssignedTo"]["displayName"]
Create your DTO structure as follows:
public class Fields
{
[JsonProperty("System.Url")]
public string SystemUrl { get; set; }
[JsonProperty("System.Type")]
public string SystemType { get; set; }
[JsonProperty("System.State")]
public string SystemState { get; set; }
[JsonProperty("System.AssignedTo")]
public SystemAssignedTo SystemAssignedTo { get; set; }
}
public class WorkItemDetail
{
public int id { get; set; }
public int rev { get; set; }
public Fields fields { get; set; }
}
public class SystemAssignedTo
{
public string displayName { get; set; }
}
here's fiddle: https://dotnetfiddle.net/F9Wppv
another way - using dynamic variable: https://dotnetfiddle.net/Goh7YY
You need to cast the object value to a JObject
((JObject)JsonConvert.DeserializeObject<WorkItemDetail>(json).fields["System.AssignedTo"])["displayName"]
JSON.Net will create a JObject if the property type is object and the value is a JSON object.
db<>fiddle
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 want to serialize/deserialize the following JSON:
{
"result": {
"ID": 1,
"TITLE": "Example",
"ARRAY": [
{
"Item1": "Result1",
"Item2": "Result2"
}
]
}
}
I tried with the following class format, but no sucess yet... Can someone help me deserialize it?
public class myClass
{
public string ID { get; set; }
[JsonProperty("TITLE")]
public string Name { get; set; }
}
obs.: Using the namespace Newtonsoft.JSON
In your example class definition above, you have called the class myClass but you would have had to call it result because ID and TITLE are members of the result JSON in the given example. myClass would not resolve to anything.
I don't know why you'd want to have a property called Name that is mapped to TITLE, but ok, if you want to do that you can modify the solution after you get it working.
Still, we're not done yet. You also have a JSON member called ARRAY and you need to define a separate class for that.
And still there is an additional problem: the result JSON is nested inside an implicit base object, so we need to define that as well. Let's call it BaseResult.
public class ARRAY
{
public string Item1 { get; set; }
public string Item2 { get; set; }
}
public class Result
{
public int ID { get; set; }
public string TITLE { get; set; }
public List<ARRAY> ARRAY { get; set; }
}
public class BaseResult
{
public Result result { get; set; }
}
If you are using Visual Studio, you can copy your JSON and paste it in any *.cs file with Edit > Paste Special > Paste JSON as Classes. It will generate POCO objects representing your JSON, which in your case will be this:
public class Rootobject
{
public Result result { get; set; }
}
public class Result
{
public int ID { get; set; }
public string TITLE { get; set; }
public ARRAY[] ARRAY { get; set; }
}
public class ARRAY
{
public string Item1 { get; set; }
public string Item2 { get; set; }
}
Then, asuming that you have your JSON in a string variable named data, you can deserialize it as follows:
var result= JsonConvert.DeserializeObject<Rootobject>(data);
I have a JSON string like this
{
"data": {
"id": "f4ba528a54117950",
"type": "password-requests",
"links": {
"self": "https://api.abc.com/api/v2/password-requests/f4ba528a54117950"
},
"attributes": {
"login": "abc",
"type": "agent",
"send-media": false,
"registration-token": "ced84635eba"
}
}
}
My classes are like this
public class SightCallResult
{
public SightCallData data { get; set; }
}
public class SightCallData
{
public string id { get; set; }
public string type { get; set; }
public Dictionary<string, string> links { get; set; }
public AgentAttributes attributes { get; set; }
}
public class AgentAttributes
{
public string Login { get; set; }
public string Type { get; set; }
public bool SendMedia { get; set; }
public string RegistrationToken { get; set; }
}
This is how I deserialize my string
sightCallRslt = JsonConvert.DeserializeObject<SightCallResult>(resultMobileToken);
sightCallData = sightCallRslt.data;
agentAttributes = sightCallData.attributes;
Debug.WriteLine(agentAttributes.RegistrationToken);
But RegistrationToken is always null. But other field values are correctly assigned. Could anybody explain what would be the reason for this.
I think you are using Newtonsoft.Json which won't automatically map a hyphenated key name to a PascalCase key name.
You maybe didn't notice it for e.g. send-media because its a non nullable / defaults to false.
If you can't change the json, you can decorate the attributes with JsonProperty:
[JsonProperty(PropertyName="send-media")]
public bool SendMedia { get; set; }
[JsonProperty(PropertyName="registration-token")]
public string RegistrationToken { get; set; }
Either change the type of attributes to Dictionary<string, object>, or if you are sure there are a finite amount of possible attributes use the JsonPropertyAttribute to specify the exact names:
[JsonProperty("registration-token")]
public string RegistrationToken { get; set; }
For deserialisation I usually use an object with the same property names as found in the JSon and JsonConvert.DeserializeObject<Des>(jsonstring).
But now I came across this:
{
"id": 0815,
"name": "whatever"
"addedInfo": {
"thisisinteresting": 4711,
"id_str": "2336"
}
}
How can I tell JSon.Net to pull the 'thisisinteresting' part of the sub category into a class like:
class Des
{
int id;
string name;
int thisisinteresting;
}
The trivial way would be to actually model your class to the JSON structure:
public class AddedInfo
{
public int thisisinteresting { get; set; }
public string id_str { get; set; }
}
public class RootObject
{
public int id { get; set; }
public string name { get; set; }
public AddedInfo addedInfo { get; set; }
}
Then add a property to the RootObject to emit the property:
public class RootObject
{
public int id { get; set; }
public string name { get; set; }
public AddedInfo addedInfo { get; set; }
[JsonIgnore]
public int thisisinteresting { get { return addedInfo.thisisinteresting; } }
}
There are alternatives like creating a custom serializer or using JObject and deserialize the structure yourself, but I won't go into that. If you need to parse the JSON anyway, the price to deserialize it entirely is small.