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.
Related
This question sounds very trivial but I couldn't find it on internet. Let's say I am getting response like following json
{
"status": 1,
"msg": "1 out of 2 Transactions Fetched Successfully",
"transaction_details": {
"f9605b13-c300-4d11-b": {
"mihpayid": "14019310624",
"txnid": "f9605b13-c300-4d11-b",
"mode": "UPI",
"status": "success",
"App_Name": "PhonePe"
},
"546576": {
"mihpayid": "Not Found",
"status": "Not Found"
}
}
}
My problem is How do I make a Model in C# (So that I can deserialize this response)?
I tried this one -
public class TransactionDetails
{
[JsonProperty("txnid")]
public string TransactionId;
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("mode")]
public string Mode { get; set; }
[JsonProperty("mihpayid")]
public string MiPayId { get; set; }
[JsonProperty("amt")]
public string amount { get; set; }
[JsonProperty("App_name")]
public string AppName { get; set; }
}
public class ResponseBody
{
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("msg")]
public string Message { get; set; }
[JsonProperty("transaction_details")]
public List<TransactionDetails> Transactions { get; set; }
}
I know the problem, Problem is "transaction_details" is not a List, It is object of object.
How do I model that, The number of Keys and name of the Keys are not known!!
Please help me!
and sorry if the question is too trivial.
Any time you are dealing with a JSON structure where the keys are not static (i.e. the key is a unique identifier, date/time, etc.) you will need to use a Dictionary. You will still have the benefit of using a strongly-typed value, and you can perform any validation operations on the key to handle different formats as necessary.
I am building chunk of code(generic) which will return list of property and values from any structure of object (either list or single object or list within single object or single object within list or list within list or single object within object) in json based on input request.
Let me explain you the use case- I am getting list of properties in accordance with class name and I need to send back its values in json in list format.
For e.g. I am getting input request for following properties SPTeam.Name, SPRole.Name, SPTeam.AltName1, Client.Name and I want to process data retrieved from DB and send its values in list format in json like,
{
"SPTeam":[
{
"Name": "AUBERT & DUVAL Development",
"AltName1": "AUBERT & DUVAL Development",
"SPRole" : [
{
"Name": "Charter Full Stack Developer II"
},
{
"Name": "General Consulting Engineer"
}]
},
{
"Name": "SmartHands_Dedicated_Team",
"AltName1": "SmartHands_Dedicated_TeamAltName1",
"SPRole" : [
{
"Name": "Accountant"
},
{
"Name": "Senior accountant"
}]
}],
"Client" : [
{
"Name": "Davita Medical Group"
}
]}
The data model or the structure from which I need to get properties and values is-
Public class SPTeam
{
public int id { get; set; }
public string Name { get; set; }
public string AltName1 { get; set; }
public string AltName2 { get; set; }
public List<SPRole> SPRole { get; set; }
}
Public class SPRole
{
public int id { get; set; }
public string Name { get; set; }
public int AvgCostHr { get; set; }
public int SellPriceHr { get; set; }
public int GPPct { get; set; }
}
Public class Client
{
public int id { get; set; }
public string Name { get; set; }
}
The data model or structure and its relationship with other classes is dynamic (not any fixed class) and I need to retrieve data only for specific properties maintaining association/relationships between them.
Any help would be appreciated...
Thanks,
Well, it seems that a core portion of your question may be resolved by the following:
How to create json structure from list of data?
However, in your case I'm not sure what level of generic capability you are requiring. You mention that "The data model or structure and its relationship with other classes is DYNAMIC (not any fixed class)" on the one hand, then you mention: "I need to retrieve data only for SPECIFIC PROPERTIES maintaining association/relationships between them".
What is the level of generic capability between, what seems to me, to be conflicting requirements? If you only want to retrieve specific properties, then where are you tracking the properties (and associated class structures) you want to retrieve?
I believe the answer you're looking for will depend on how you answer this.
I'm trying to convert a string of JSON data into a C# class object. However I'm having an issue with a small part of the JSON which is dynamic in nature.
The part of the JSON is below:
"contact": [{
"comment": null,
"type": {
"id": "cell",
"name": "Example name"
},
"preferred": true,
"value": {
"country": "7",
"formatted": "+7 (702) 344-3423-3",
"number": "3498908",
"city": "702"
}
},
{
"type": {
"id": "email",
"name": "Email example"
},
"preferred": false,
"value": "name#mail.com"
}]
C# classes
public class Value
{
public string country { get; set; }
public string formatted { get; set; }
public string number { get; set; }
public string city { get; set; }
}
public class Type
{
public string id { get; set; }
public string name { get; set; }
}
public class Contact
{
public string comment { get; set; }
public Type type { get; set; }
public bool preferred { get; set; }
public string value { get; set; }
}
C# Code
Contact contact = JsonConvert.DeserializeObject<Contact>(result);
The format of "value" changes depending on the contact information. Is it possible to map value both as a string and also class Value.
Thanks for any help that can be provided.
You can literally just use dynamic, i.e.
public dynamic value { get; set; }
If it looks like an object, it will be materialized as a JObject, which can be used via the dynamic API, so .value.country will work, etc. If it looks like an integer, bool or string: it will be materialized as such. Arrays will also be handled suitably. So: you can check whether .value is string, etc. Note that this won't use your Value type, and doing so is more complex, but: meh; you get the data. You can always switch that out manually.
It will also behave like this if you use object instead of dynamic, but then it is harder to access the inner properties.
Try
Contact contact = JsonConvert.DeserializeObject<Contact>(result[0]);
As you can see in the JSON, it's
"contact": [
Indicating an array, currently you're just passing the entire array
Unless you're sure that the JSON comes always with the same structure, the best is to use a dynamic variable instead of deserialize it into a class.
If you like to work with classes you can always build your own on runtime using reflection. But that's like killing a fly with a cannon and you're probably won't need it, so just use a dynamic variable instead, it's the best to work with JSON strings.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have JSON in this format:
{
"user": "123#abc",
"filter": [
{
"filterName": "Filter1",
"condition": "1",
"values": [
"123"
]
},
{
"filterName": "Filter2",
"condition": "2",
"values": [
"ABC",
"XYZ"
]
}
],
"onlyMerge": "true",
"mergeBy": [
]
}
And I am using these classes
public class Outermost{
public string user;
public Root filter ;
public string onlyMerge;
public string mergeby;
}
public class values {
public string value { get; set; }
}
public class Filters {
public string filtername {get; set; }
public string condition {get; set;}
public values values { get; set; }
}
public class Root {
public List<Filters> Filters { get; set; }
}
JSONConvert.Deserialize(Outermost)
I have to deserialize the structure
Paste your JSON into http://json2csharp.com/ and you will see that your C# classes don't match the JSON.
Update 2:
Visual Studio 2013 has a built-in Json to C# Class converter tool! :)
Update:
Just a note about the great tool http://json2csharp.com/ : When working with a object that has properties of complex types, You may want to check about the classes it creates, because sometimes it'll created unnecessarily/undesirable classes. Example:
Json
var objJson = {
"id_product": 19,
"description": "Laptop",
"_links": {
"buy": {
"href": "/Product/Buy/19",
"title": "Buy It Now!"
},
"more_details": {
"href": "/Product/Details/19",
"title": "More Details..."
}
}
};
Generated Class/Classes:
public class Buy
{
public string href { get; set; }
public string title { get; set; }
}
public class MoreDetails
{
public string href { get; set; }
public string title { get; set; }
}
public class Links
{
public Buy buy { get; set; }
public MoreDetails more_details { get; set; }
}
public class RootObject
{
public int id_product { get; set; }
public string description { get; set; }
public Links _links { get; set; }
}
As You can see, the two classes Buy and MoreDetails have exactly the same structure and purpose, so You may want to replace it with a more generic class instead of using repeatedly classes (there are scenarios where this redundant structure is more appropriate). In a very similar scenario, I've created a class named Link.
Original Answer:
You don't said enough to be sure what's your problem. Try in the future specify better what are your difficulties and needs.
But, I guess your problem is some exception being throw or some properties not being bind...
If you pay attention, in your JSON example object, filter is directly a collection, and not a property that has a collection inside. Thus, just change
public Root filter; to public List<Filters> filter { get; set; }.
Also, mergeBy and values are collections, and not simple strings. You could use http://json2csharp.com/ to generate automatically the correspondent C# class of your JSON object, and check what properties are not matching... (Or, substitute your whole class, that is what I would recommend...)
Current I have a project where I'm getting the following sample data ( I want to retrieve only the ids within this json string and stuff them into IEnumerables (explained below):
{
"states": [
{
"id": "AL",
"text": "Alabama (AL)"
},
{
"id": "CO",
"text": "Colorado (CO)"
}
],
"cities": [
{
"id": 71761,
"text": "New Brockton, AL"
},
{
"id": 74988,
"text": "Nathrop, CO"
}
],
"zipCodes": []
}
Notice in the zipCodes, I am getting an empty set, so there is no "id" or "text".
I want to be able to create several IEnumerables from the properties found in this JSON string.
I created an object called Locations that looks like this:
public class Location
{
public IEnumerable<string> States { get; set; }
public IEnumerable<string> ZipCodes { get; set; }
public IEnumerable<decimal> Cities { get; set; }
}
The best way I found to going about this approach is to do each data property one by one and convert, formValues is the json string:
JArray arrStates = (JArray)formValues["states"];
JArray arrCities = (JArray)formValues["cities"];
JArray arrZip = (JArray)formValues["zipCodes"];
and then set the properties in the location object as so:
Location loc = new Location();
loc.States = arrStates.Children().Select(m=>m["id"].Value<string>());
loc.ZipCodes = arrCities.Children().Select(m=>m["id"].Value<string>());
loc.Cities = arrZip.Children().Select(m=>m["id"].Value<string>());
I was wondering if there's a better way of doing this instead of doing all this code maintenance for whenever my json response adds a new property. In fact, I think there's going to be about ten more properties added to the json string.
I want it to be reduced down to where I could just update the Location object, and have the json automatically map to the properties that way. Or atleast a solution that has less maintenance than what I'm doing now.
Also I was wondering if JsonConvert.DeserializeObject would work in my case; but read that JSON.NET treats an IEnumerable as an array, so I'm stumped on this one.
JsonConvert.DeserializeObject would work in your case and it will have less maintenance than what you're doing now.
If you enter your json data to http://json2csharp.com, below is the generated class definition that you can use, I renamed RootObject to Location
public class State
{
public string id { get; set; }
public string text { get; set; }
}
public class City
{
public int id { get; set; }
public string text { get; set; }
}
public class Location
{
public List<State> states { get; set; }
public List<City> cities { get; set; }
public List<object> zipCodes { get; set; }
}
This is how you deserialize the json data into Location
string jsonData = ...; // set the json data here
var location = JsonConvert.DeserializeObject<Location>(jsonData);
You can enumerate through the nested properties to get the ids, for example location.states[0].id will return "AL" and location.cities[1].id will return 74988.
If there's a new property in the json data, let's say it's named countries with id and text like in states, you can create a new Country class
public class Country
{
public string id { get; set; }
public string text { get; set; }
}
and add countries property to Location class
public class Location
{
public List<State> states { get; set; }
public List<City> cities { get; set; }
public List<object> zipCodes { get; set; }
public List<Country> countries { get; set; }
}