JSON deserialization, get properties name not value [duplicate] - c#

This question already has answers here:
How can I deserialize this JSON with JsonConvert?
(2 answers)
Closed 6 years ago.
First of all, this question may have been asked before, but I couldn't find an answer due to poor wording I guess.
I get a weirdly formatted JSON string back from a WebService call
{
"id":5000174774,
"name":"company_name",
"choices":
{
"Farmway":
{
"Head Office (BSU)":[],
"Alnwick":[],
"Bury St Edmunds":[]
},
"Tate":
{
"Head Office":[],
"Tate Britain Entrance":[]
}
}
}
Here are the classes I'd like to use for deserialization
public class RootObject
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("choices")]
public Company[] Companies{ get; set; }
}
public class Company
{
public string[] Shops { get; set; }
}
I've never seen a JSON formatted like that, and I have no idea how to get the properties name instead of values. "choices" is not an array but an object, but I can't know its properties beforehand. I just want to get all companies and their shops.
I hope it makes some kind of sense.

I don't know about your deserializer, but usually a good candidate is a Dictionary:
[JsonProperty("choices")]
public Dictionary<string, Dictionary<string, List<OfSomething>> Companies { get; set; }
So, your first key is a string, with the name of the company, and the value is another dictionary, linking company BU's to list/arrays of I-don't-know-what.
If you then need to elaborate this structure into something else, you can process it with a bit of Linq.

Related

Creating a C# class for JSON deserialization [duplicate]

This question already has answers here:
Deserializing JSON with dynamic keys
(4 answers)
Complicated Json to C# Object Deserialize with classes
(2 answers)
Using JSON.NET to read a dynamic property name
(1 answer)
Closed 10 months ago.
I'm having an issue with JSON that I'm getting back for a hotel booking API. Essentially I'm taking the output and trying to create a class so that I can put it into an object. The problem is this: The JSON is returning objects and we can't readily use this format to make a C# class because of how it's formatted:
Example of how the JSON is formatted
Here is a snippet of it. Attributes is the highest level, then "pets" is next. The values we need for this are id: 5058 and name: Service Animals are allowed, however they are creating this "5058" and "5059" and "2050" object which is making it difficult to create a class and properly deserialize it.
I'm fairly new at C# (formerly long-time C programmer), so trying to understand the best way to make a class for something like this where the "5058" is not actually created as a class ... I would prefer if we could ingest that level into an array or list perhaps?
This is what something like json2csharp.com outputs...
public class Pets
{
public _5058 _5058 { get; set; }
public _5059 _5059 { get; set; }
public _2050 _2050 { get; set; }
}
And then
public class _5059
{
public string id { get; set; }
public string name { get; set; }
}
5059 should not be a class... That appears to be the name of the object; I want to ignore that because the ID: in the object is 5059
This wont work since there are thousands of IDs, and we're not looking to create a separate class for each ID -
I would like to make a class more like this
public class Pets
{
public string id { get; set; }
public string name {get; set; }
}
This is how I'm receiving the JSON
{
"pets":{
"5058":{
"id":"5058",
"name":"Service animals are allowed"
},
"5059":{
"id":"5059",
"name":"Service animals are exempt from fees/restrictions"
},
...
}
}
(This is a small snippet)
Again, here, they have "5059":{"id":"5059","name":"Service animals...."
So, what's the best way to ingest this with a class in C# without creating classes for the ID, the way a JSON to C# class creator would do?
Thanks for you help
That looks like a Dictionary<string, Pet> where those 5058, 5059, etc. are the keys.
public class Data
{
public Dictionary<string, Pet> pets { get; set; }
}
public class Pet
{
public string id { get; set; }
public string name { get; set; }
}
Deserialize the json as below
var data = JsonSerializer.Deserialize<Data>(json);
or if you're using Newtonsoft.Json
var data = JsonConvert.DeserializeObject<Data>(json);

How can I parse JSON Array to string? [duplicate]

This question already has answers here:
How can I deserialize JSON with C#?
(19 answers)
Closed 2 years ago.
I'm trying to get JSON content with Newtonsoft.Json. To read one variable i have that method and It's working fine:
dynamic data = JObject.Parse(json);
return data.FirstName;
The problem begins if I want to read variable which is in array ex:
{"family": [{"fatherFirstName": "John", "motherFirstName": "July"}, {"fatherFirstName": "Jack", "motherFirstName": "Monika"]}
And for example I only want to get every father's first name.
Anybody know how can I do this?
Edit1:
Ok I fixed the convert from JArray to string but now there is problem that It reads family variable properly but If I want to get exact variable from Array it says that variable like this doesn't exist.
First of all, your JSON string has an invalid format. You can check it here to validate. Secondly, the best way to do this is to create a class and than use JsonConvert.DeserializeObject. On your case, here is the full working solution:
static void Main(string[] args)
{
string json = #"{'family': [{'fatherFirstName': 'John', 'motherFirstName': 'July'}, {'fatherFirstName': 'Jack', 'motherFirstName': 'Monika'}]}";
Families families = JsonConvert.DeserializeObject<Families>(json);
foreach (var family in families.family)
Console.WriteLine(family.fatherFirstName);
}
public class Families
{
public List<Family> family { get; set; }
}
public class Family
{
public string fatherFirstName { get; set; }
public string motherFirstName { get; set; }
}
public class familyData
{
public string fatherFirstName {get; set;}
public string motherFirstName {get; set;}
}
public class familyList
{
public List<familyData> family
}
and in your method
var data = JsonConvert.DeserializeObject<familyList>(json);

Creating data model to accept all JSON C# [duplicate]

This question already has answers here:
Deserialize JSON with C#
(10 answers)
Closed 5 years ago.
So I'm creating an endpoint using a data model called Chat that will accept data in this JSON form and store it in the database.
[{
"ID": "123456",
"Chat": [{
"ID": "1",
"Message": "User: that's a nice car Dylan: thanks",
"PostedBy": "Dylan",
"PostedOn": "2018-01-23T18:25:43.511Z"
},
{
"ID": "2",
"Message": "User: that's a really nice car Terry: thanks ",
"PostedBy": "Terry",
"PostedOn": "2018-02-23T18:25:43.511Z"
},
{
"ID": "3",
"Message": "User: that's the best car Roger: thanks",
"PostedBy": "Roger",
"PostedOn": "2018-03-23T18:25:43.511Z"
}
]
}]
This is what I have currently and when I send data to the endpoint it only stores the ID, and nothing else in the database. Any thoughts/guidance is appreciated on how I could alter my model to accept the entirety of the data that is being sent.
public class Chat
{
public string ID { get; set; }
public string message { get; set; }
public string postedBy { get; set; }
public DateTime? postedOn { get; set;}
}
I may be wrong here, but it seems to me like you're using a class that represents a single message-instance (the class Chat) to attempt to store a whole list of Chat-data.
If I'm right, the only reason it actually stores ID is that it by chance happens to have the same name for two different levels in your data; one for the outer list (the whole set - and this is what is stored), and one for each of the inner chat-items.
Try to add this class, and use that instead (or rather in addition, since it actually contains a list of instances of your already existing class Chat):
public class ChatThread
{
public string ID { get; set; }
public IEnumerable<Chat> Chat { get; set; }
}
The ID which is being stored on your object is not the ID from the Chat object, but rather the higher ID definition which is common to your Chat objects.
You're were really close, if we discount the fact that you have not taken into consideration that C# is a case-sensitive language.
The "higher" layer is composed of a String ID, but also of an array of Chat objects, so you should create a Class that holds the definition of these two properties.
public class JsonClass
{
public string ID { get; set; }
public Chat[] Chat { get; set; }
}
public class Chat
{
public string ID { get; set; }
public string Message { get; set; }
public string PostedBy { get; set; }
public DateTime PostedOn { get; set; }
}
Since there exist multiple Chat objects for the JsonClass ID property, you have to make it into a collection of some sort. I chose an array, but you can use other Collection objects, such as a List.

Deserialize object using JSON.NET, but put some properties into a member of the class

I am writing a set of data structures to ingest third-party JSON into (no writing out) using JSON.NET.
I have a case for reading some of the top-level JSON elements into a member object of the object being deserialized into.
My JSON:
{
"Id":1
"Checksum":42
"Name":"adam",
"Hair":true
}
My ideal object structure:
public class EntityHeader
{
int Id { get; set; }
int Checksum { get; set; }
}
public class Entity
{
[HeroicJsonAttribute( "Id", "Checksum" )]
public EntityHeader Header { get; set; }
public string Name { get; set; }
public bool Hair { get; set; }
}
Is there a simple way to achieve this? I will have a number of types which will need this, and I'd hate to have to write a JsonConverter for each.
This question has been asked before, here, but the accepted answer doesn't address the question.
Thanks!
An alternative approach would be to use an EntityHeader field in the Entity class as a backing store for private properties which can be deserialized into:
public class EntityHeader
{
int Id { get; set; }
int Checksum { get; set; }
}
public class Entity
{
private EntityHeader m_Header = new EntityHeader();
public EntityHeader Header { get { return m_Header; } }
[JsonProperty]
private int Id { set { m_Header.Id = value; } }
[JsonProperty]
private int Checksum { set { m_Header.Checksum = value; } }
public string Name { get; set; }
public bool Hair { get; set; }
}
Thus, all the properties in the JSON can be read straight into the Entity object, but consumers of Entity objects have access to a "nicely encapsulated" EntityHeader property.
I haven't tested this, and it may even be kludgey, but it would technically work for me (OP). I am still interested in other answers!
Base on your example you could either; use the adapter pattern:
public class EntityJson
{
int Id { get; set; }
int Checksum { get; set; }
public string Name { get; set; }
public bool Hair { get; set; }
}
// quick/poor example
public class EntityAdapter : IEntity
{
public EntityAdapter(EntityJson model)
{
Header = new Header(); // and populate this objects fields
Name = model.Name; // populate other properties
}
public EntityHeader Header { get; set; }
public string Name { get; set; }
public bool Hair { get; set; }
}
Or abuse the fact that json.net ignores properties not available:
var entity = JsonConvert.Deserialze<Entity>();
var header = JsonConvert.Deserialize<EntityHeader>();
entity.Header = header;
I'm going to go ahead and post this answer which is a little bit too long for a comment, so please take this more as an extended comment than an actual attempt to answer your specific question. And of course, you know your requirements best so this is just my considered opinion :)
With that in mind, my advice is:
Don't do this.
I would instead create a simple DTO class that has a 1-1 relationship to the JSON being received; and I'd put all my validation attributes on the properties of that class.
Once I had deserialised the JSON into this simple DTO, I would then use a mapping layer of some kind (roll your own or use Automapper, etc) to map this DTO into a more meaningful structure such as your Entity class.
My reasoning behind this is because unless your Entity class is itself only a simple DTO (in which case it should be as simple as possible and ideally not be a composite) you are mixing OOP and concerns with data mapping concerns; whilst this in and of itself is not such a bad thing, it only serves to increase the complexity of your code.
Consider for example if your incoming JSON ends up with 30 or 40 properties, and you manage to figure out a way (maybe adapting some of the nice techniques from the other answers) to map it to the Entity class. But what about when something goes wrong - it's going to be much easier to reason about, and therefore debug, a process which you have much more control over; it's also going to be much easier to make special adaptations for odd edge cases where the serialiser behaviour just can't help you out
Granted it's a bit of work to write and maintain these DTOs but not that much - Webtools already does this for you
Reference: At the boundaries, Applications are not Object-Oriented

C# Json Deserialization

I have been asked to work with json data in order to create a quiz game in windows phone. I knew that I had to use json.net to achive this which I have previously used in the past but the method I used in the past is no useful here.
My question is this. I have this json string
[{"corr":"1","q":"text.","type":"0"},
{"corr":"0","q":"text.","type":"0"},
{"corr":"1","q":"text.","type":"0"},
{"corr":"0","q":"text.","type":"0"},
{"corr":"0","q":"text.","type":"0"},
{"corr":"1","q":"text.","type":"0"},
{"corr":"4","q":"text","a":["text","text","text","text"],"type":"1"},
{"corr":"2","q":"text","a":["text","text","text","text"],"type":"1"},
{"corr":"1","q":"text","a":["text","text","text","text"],"type":"1"},
{"corr":"2","q":"text","a":["22,2%","45%","54%","67%"],"type":"1"}]
and as you can image I want to fill some List with the properties above.
I have created the following class in order to represent the json objects
public class QuizObj
{
public string corr { get; set; }
public string q { get; set; }
public string type { get; set; }
public List<string> a { get; set; }
}
but I don't really know how to use it and can't find something really relevant.
Something like this should do the trick:
var quizObjs = JsonConvert.DeserializeObject<List<QuizObj>>(serializedStringValue);
string corr = quizObjs.First().corr;
// or
foreach(var quizObj in quizObjs)
{
string corr = quizObj.corr;
// etc
}
You will need to add a reference to NewtonSoft.Json, which you can get via NuGet (if you haven't already).

Categories

Resources