Dynamic json property deserialize - c#

I'm having difficulties figuring out how to deserialize a json, that has a dynamic property (for example - UserRequest::567) the property name can be any value and the UserRequest object contains other json properties that are of interest to me
I tired writing a class and I don't know what to do with that property. What are the best practices for coping with a problem like this?
{
"objects": {
"UserRequest::567": {
"code": 0,
"message": "created",
"class": "UserRequest",
"key": "567",
"fields": {
"ref": "R-000567",
"org_id": "4"
}
}
}
}
The question is what are the best practices to read through this kind of a json string?
Thank you

To Deserialize this using Newtonsoft.Json, here are the classes:
public class CreateRequest
{
public long code { get;set; }
public string message { get; set; }
[JsonProperty("class")]
public string class1 { get; set; }
public string key { get; set; }
public Fields fields { get; set; }
}
public class Fields
{
[JsonProperty("ref")]
public string refe { get; set; }
public string org_id { get; set; }
}
public class Root
{
public Dictionary<string, CreateRequest> objects { get; set; }
//The 'string' key in the dictionary is the 'UserRequest::567'
}
Then to Deserialize use:
var x = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(jsonObject).objects.Values;

Related

Deserializing JSON when inner property names vary

I have JSON which looks something like this (external JSON beyond my control):
[
{
"currencies": {
"KGS": {
"name": "Kyrgyzstani som",
"symbol": "с"
}
}
},
{
"currencies": {
"SOS": {
"name": "Somali shilling",
"symbol": "Sh"
}
}
}
]
And I have a set of classes which I would like this JSON deserialized into
public class ParentClass
{
public OuterClass Currencies { get; set; }
}
public class OuterClass
{
//Inner property below needs to map to these changing prop names: "KGS", "SOS"
public InnerClass Inner { get; set; }
}
public class InnerClass
{
public string Name { get; set; }
public string Symbol { get; set; }
}
And Lastly, when I try to deserialize:
JsonConvert.DeserializeObject<IList<ParentClass>>(responseBody.Content);
It's not deserializing properly, because the it cannot map varying Property names to "Inner". Is there a way to handle this scenario?
Newtonsoft didn't seem to have any problem with it..
public partial class Blah
{
[JsonProperty("currencies")]
public Dictionary<string, Currency> Currencies { get; set; }
}
public partial class Currency
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("symbol")]
public string Symbol { get; set; }
}
And
var blah = JsonConvert.DeserializeObject<Blah[]>(jsonString);
..though it's probably worth noting I think you have your parent and outer the wrong way round if this json is just a fragment..

deserializing dynamic named JSON attributes to a C# class

{
"Documents": {
"c97bba6f-c8ab-4453-91f8-f663f478910c": {
"id": "c97bba6f-c8ab-4453-91f8-f663f478910c",
"name": "name",
"sys": {
"c67bfa6f-c8ab-4453-91f8-f663f478910c": {
"id": "c97bba6f-c8ab-4453-91f8-f663f478910c",
"name": "sys name"
},
"a67bfa6f-c8ab-4453-91f8-f663f478910c": {
"id": " a67bfa6f-c8ab-4453-91f8-f663f478910c",
"name": "sys name"
}
}
},
"f97bba6f-c8ab-4453-91f8-f663f478910c": {
"id": "c97bba6f-c8ab-4453-91f8-f663f478910c",
"name": "OZL - B - MECH - AC - Fan Coil Units",
"sys": {}
}
}
}
I've got JSON data in the form above and am having trouble deserializing this into a C# class. The trouble I'm having is that the GUID is used to define the object that the Documents object has rather than the documents object having a list of documents.
I've tried to create a documents object that has a list of object in it and deserialise into this using Newtonsoft. I've also tried a dictionary of string, object in the documents object. None of these work.
Any input or ideas would be most appreciated.
Edit: the biggest issue I'm having is the nesting of Dictionary<GUID, object>. Newtonsoft won't map to the dictionary within the first object. Here's what I have:
public class Documents {
public dictionary<Guid, System> data { get; set; }
}
public class System {
public Guid Id { get; set;}
public string Name { get; set; }
public dictionary<guid, someOtherobject> otherData { get; set;}
}
Based on your JSON, the class structure you need is this:
public class RootObject
{
public Dictionary<Guid, Document> Documents { get; set; }
}
public class Document
{
public Guid Id { get; set; }
public string Name { get; set; }
public Dictionary<Guid, Sys> Sys { get; set; }
}
public class Sys
{
public Guid Id { get; set; }
public string Name { get; set; }
}
Then deserialize into the RootObject class like this:
var root = JsonConvert.DeserializeObject<RootObject>(json);
Here is a working demo: https://dotnetfiddle.net/Uycomw

JsonConvert deserialize only Class fields

This is json:
{
"odata.metadata": ".....",
"value": [
{
"AbsEntry": 10,
"ItemNo": "....",
"UoMEntry": -1,
"Barcode": "2000000000022",
"FreeText": "Ean13"
}
]
}
This is class:
public class BarCode
{
public int AbsEntry { get; set; }
public string ItemNo { get; set; }
public string Barcode { get; set; }
public string FreeText { get; set; }
}
This method return null:
BarCode barcode = JsonParser.DeserializeObjcet<BarCode>(json);
Are there any properties or other that can cause the call DeserializeObject to deserialize me only the fields of my classes (the names are exactly those of the Json)?
You need to create class like below not BarCode
public class Value
{
public int AbsEntry { get; set; }
public string ItemNo { get; set; }
public int UoMEntry { get; set; }
public string Barcode { get; set; }
public string FreeText { get; set; }
}
or you can change the JSON format
"BarCode": [
{
"AbsEntry": 10,
"ItemNo": "....",
"UoMEntry": -1,
"Barcode": "2000000000022",
"FreeText": "Ean13"
}
]
The structure of your class should match the structure of your JSON if you want the deserialization to succeed.
If you want a partial deserialization e.g. only deserializing the values property into your class you can use this code:
JObject jObject = JObject.Parse(json);
BarCode barcode = jObject["values"].Children().First().ToObject<BarCode>();
With this solution you don't need to refactor your class or adding a new one.
You are missing the root object :
public class RootObject
{
public string __invalid_name__odata.metadata { get; set; }
public List<BarCode> value { get; set; }
}
note that the invalid name oprperty can just be remove so it will be igrored!
Even if you want only the Value part you will have to deserialise from the root, then navigate to the child properties you need.

Put JSON data into c# datatable

I am trying to deserialise some JSON that I get back from an API so that I can loop through an array of county names and add the information to a datatable in C#. However I am receiving following error at the first hurdle when I try and deserialise it:
error: System.MissingMethodException: No parameterless constructor defined for type of 'DPDJSONLibrary.DPD_JSON+LOCR_Data[]'.
The provider of the API provides an example of the JSON response as follows:
{
"error": null,
"data":[{
"country": [{
"countryCode":"GB",
"countryName":"United Kingdom",
"internalCode":"UK",
"isEUCountry":false,
"isLiabilityAllowed":false,
"isoCode":"826",
"isPostcodeRequired":false,
"liabilityMax":15000
}]
}]
}
A sample of the JSON data I am getting back from the API is:
{
"data": {
"country":[
{
"countryCode":"PM",
"countryName":"St Pierre & Miquilon",
"isoCode":"666",
"isEUCountry":false,
"isLiabilityAllowed":true,
"liabilityMax":15000,
"isPostcodeRequired":true
},
{
"countryCode":"SR",
"countryName":"Suriname",
"isoCode":"740",
"isEUCountry":false,
"isLiabilityAllowed":true,
"liabilityMax":15000,
"isPostcodeRequired":true
},
{
"countryCode":"SZ",
"countryName":"Swaziland",
"isoCode":"748",
"isEUCountry":false,
"isLiabilityAllowed":true,
"liabilityMax":15000,
"isPostcodeRequired":true
}
]
}
}
I have tried to make some classes to put the JSON in as follows:
/// <summary>
/// List Of Countries Response object.
/// </summary>
public class LOCR
{
public LOCR_Error error { get; set; }
public LOCR_Data[] data { get; set; }
}
public class LOCR_Error
{
public string errorAction { get; set; }
public string errorCode { get; set; }
public string errorMessage { get; set; }
public string errorObj { get; set; }
public string errorType { get; set; }
}
public class LOCR_Data
{
public LOCR_Data_Country[] country { get; set; }
}
public class LOCR_Data_Country
{
public string countryCode { get; set; }
public string countryName { get; set; }
public string internalCode { get; set; }
public bool isEUCountry { get; set; }
public bool isLiabilityAllowed { get; set; }
public string isoCode { get; set; }
public bool isPostcodeRequired { get; set; }
public int liabilityMax { get; set; }
}
When I get the JSON back as a string, I am trying to use the Newtonsoft (plugin?) to put it into my classes using:
JavaScriptSerializer ser = new JavaScriptSerializer();
DPD_JSON.LOCR DPDCountries = new DPD_JSON.LOCR();
DPDCountries = ser.Deserialize<DPD_JSON.LOCR>(data);
It is the last line above that is generating the error. I suspect I've written my classes wrong that I am trying to deserialise the JSON in to - can anyone see where I've gone wrong?
Deserialize will return a list and not an array, So your LOCR_Data_Country should be of type List and not array:
public class LOCR_Data
{
public List<LOCR_Data_Country> country { get; set; }
}
There's a HUGE difference between the two example JSON strings you've shown. Mainly the first one is an array : "data":[ ... ] and the second one is an object "data:{ ... }. These two are not interchangeable so you have to stick to either one of those. If the thing you're getting back from the API is an object instead you should rewrite your model to be :
public class LOCR
{
public LOCR_Error error { get; set; }
// object here since "data": { ... }
public LOCR_Data data { get; set; }
}
And as you move further with the JSON you can see that LOCR_Data.country is in fact an array in both cases "country": [ ... ] so you can stick with the current implementation of LOCR_Data class.
Try Using :
YourResultClass object = JsonConvert.DeserializeObject<YourResultClass>(Jsonstring);
See the answer of this Using JsonConvert.DeserializeObject to deserialize Json
OR
dynamic data = Json.Decode(json);
You can refer this Deserialize JSON into C# dynamic object? for further assistance

How to get inner field's value of object by using JsonProperty

I have data in json like this:
{
"data": {
"name" : "Car wash"
"changed_by": {
"id": 1,
"name": "Pascal",
"type": "user"
}
}
}
The value "Car wash" I can get like this:
public class Changes
{
[JsonProperty("name")]
public string name { get; set; }
}
How I can get the value of some changed_by object field?
I need to use this in deserializing
private void GetChanges(RawData data)
{
var changes = JsonConvert.DeserializeObject<Response<IEnumerable<Model.Json.Changes>>>(data.ChangesData);
/* some code */
}
You just need to have a class that represents the changed_by object. For example:
public class Data
{
public string name { get; set; }
public ChangedBy changed_by { get; set; }
}
public class ChangedBy
{
public int id { get; set; }
public string name { get; set; }
public string type { get; set; }
}
Create a class hierarchy representing the structure of the data in and then use Json.Net to deserialize it into an object of this class.
Check out Json.Net

Categories