C# JSON Deserialize Dictionary<string, Dictionary<string, string>> optional? - c#

My payload would look something like this:
{
"REFERENCE": "1",
"FIELDS" : {
"CUST" : "1234",
"PROD" : "PR2134",
"LIMIT" : "12345",
"LINES" : {
"LINE" : "01",
"DATA" : "12"
}
}
}
My object simply has the following:
public class TriggerRequest
{
public string reference { get; set; }
public Dictionary<string, string> fields { get; set; }
}
Obviously, this doesn't handle the LINES object. How can I create a class that deserializes an inbound payload where something like LINES is dynamic (i.e. I can send in any Dictionary> at any point in the payload and it'll deserialize correctly. Is this something when I need to create a custom JsonConverter?

You could use dynamic instead.
public class TriggerRequest
{
public string reference { get; set; }
public dynamic fields { get; set; }
}
This should allow you to access (string)request.fields.lines.data directly in your code, for example.
However, if you don't know at compile time what values will be in there, you may prefer to make fields a JObject.
public class TriggerRequest
{
public string reference { get; set; }
public JObject fields { get; set; }
}
This gives you the opportunity to write code that inspects what kind of data is in each of its properties and respond accordingly.
Finally, if you do know what properties you expect fields to have, create a separate class for it.
public class TriggerRequest
{
public string reference { get; set; }
public TriggerRequestFields fields { get; set; }
}
public class TriggerRequestFields
{
public string cust {get;set;}
...
public TriggerRequestLines lines {get;set;}
}
public class TriggerRequestLines
{
public string line {get;set;}
public string data {get;set;}
}

Try changing
public Dictionary<string, dynamic> fields { get; set; }
With
public Dictionary<string, object> fields { get; set; }

Related

In c# when using JsonConvert.DeserializeObject into a class, how to convert a decimal to a string within a subclass?

Modified post to simplify problem:
I have a json object that has the below structure. (data is faked)
I am attempting to deserialize this object using the common Newtonsoft JsonConvert functionality into a class named "Work"
var jWork = JsonConvert.DeserializeObject<Work>(strResponse);
My issue is that if I define the Work class to have public fields as strings, the DeserializeObject will correctly convert the Json values as strings. In other words I can correctly convert the "StringDate" Json field when I have a class defined like below.
However if I define the subfields as classes themselves, the deserialize object no longer works and I get a conversion error.
In other words when I try to do public string DateValue {get ; set} inside of the "Person" class it throw a conversion error.
Why is this?
public partial class Work
{
public Issues Issues { get; set; }
}
public partial class Issues
{
public string Id { get; set; }
public Fields Fields { get; set; }
}
public partial class Fields
{
public string StringDate { get; set; }
public Person Person { get; set; }
public object Customfield11600 { get; set; }
}
public partial class Person
{
public string Name { get; set; }
public string Income { get; set; }
/* I don't want this to be a DateTimeOffset?, i want it to read in the value as string, but if you put string here deserialize throws a conversaion error*/
public DateTimeOffset? Datevalue { get; set; }
/*above works, this doesn't*/
***public string Datevalue { get; set; }***
}
}
Can anyone explain why this is true?
{
"issues" : {
"id": "test",
"fields": {
"StringDate": "2020-02-02",
"person" : {
"name" : "baby",
"Income" : "50000.22",
"datevalue" : "2020-02-02"
},
"customfield_11600": null
}
}
}

json properties as numbers in c# model class?

How can I build a Model class to deserialize a json like this:-
{"query":{"apikey":"65320-2d8b-11eb-864","continent":"Africa"},"data":{"0":{"country_id":1,"name":"Africa","country_code":null,"continent":"Africa"},"9":{"country_id":10,"name":"Algeria","country_code":"dz","continent":"Africa"},"11":{"country_id":12,"name":"Angola","country_code":"ao","continent":"Africa"},"23":{"country_id":24,"name":"Botswana","country_code":"bw","continent":"Africa"},"27":{"country_id":28,"name":"Cameroon","country_code":"cm","continent":"Africa"},"32":{"country_id":33,"name":"Congo","country_code":"cg","continent":"Africa"},"39":{"country_id":40,"name":"Egypt","country_code":"eg","continent":"Africa"},"48":{"country_id":49,"name":"Ghana","country_code":"gh","continent":"Africa"},"62":{"country_id":63,"name":"Ivory Coast","country_code":"ci","continent":"Africa"},"67":{"country_id":68,"name":"Kenya","country_code":"ke","continent":"Africa"},"80":{"country_id":81,"name":"Morocco","country_code":"ma","continent":"Africa"},"85":{"country_id":86,"name":"Nigeria","country_code":"ng","continent":"Africa"},"102":{"country_id":103,"name":"Rwanda","country_code":"rw","continent":"Africa"},"106":{"country_id":107,"name":"Senegal","country_code":"sn","continent":"Africa"},"111":{"country_id":112,"name":"South Africa","country_code":"za","continent":"Africa"},"115":{"country_id":116,"name":"Tanzania","country_code":"tz","continent":"Africa"},"118":{"country_id":119,"name":"Tunisia","country_code":"tn","continent":"Africa"},"120":{"country_id":121,"name":"Uganda","country_code":"ug","continent":"Africa"},"129":{"country_id":130,"name":"Zambia","country_code":"zm","continent":"Africa"},"130":{"country_id":131,"name":"Zimbabwe","country_code":"zw","continent":"Africa"}}}
The problem is in the numbers like "0", "9", "11" etc! How can I convert these numbers to one property in the model class?
If you implement the data item as a Dictionary on your model, these numbers would be the keys of this Dictionary.
public class Model
{
[JsonProperty("query")]
public Query query {get; set; }
[JsonProperty("data")]
public Dictionary<string, Country> Data { get; set; }
}
public class Country
{
[JsonProperty("country_id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("country_code")]
public string Code { get; set; }
[JsonProperty("continent")]
public string Continent { get; set; }
}
public class Query
{
[JsonProperty("apikey")]
public string ApiKey { get; set; }
[JsonProperty("continent")]
public string Continent { get; set; }
}
You can treat these numbers as keys of an dictionary. So may convert them like this:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var testJson = "{\"data\":{\"11\": \"test11\"}}";
var deserialized = (TestClass) JsonConvert.DeserializeObject(testJson, typeof(TestClass));
Console.WriteLine(deserialized.Data[11]);
}
}
public class TestClass
{
public Dictionary<int, string> Data {get;set;}
}
(to test see this dotnetfiddle example)
Obviously only possible if no number appears twice or more.

Custom JSON Serialize with custom mapping C#

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);

How to deserialize a Json string that has an array of objects but is not using square brackets

I'm trying to deserialize a Json string that has an array with no containing brackets.
{ "id": "983f90j30909j3f",
"moreInfo": {
"info193802": { ... },
"info920938": { ... },
"info849028": { ... }
}
}
This "moreInfo" is an array of items with dynamic keys and does not have square brackets telling that it's an array.
I've tried to deserialize it with Newtonsoft.Json normally ( JsonConvert.DeserializeObject<rootObject>() ) but since this json array isn't really an array it throws an error. Here is my class:
public class RootObject
{
public string Id { get; set; }
public MoreInfo MoreInfo { get; set; }
}
public class MoreInfo
{
public List<Info> InfoList{ get; set; }
}
public class Info
{
properties...
}
How do I go about deserializing this?
Update the root object to use IDictionary<string, Info>
public class RootObject {
public string Id { get; set; }
public IDictionary<string, Info> MoreInfo { get; set; }
}
the dynamic keys will be the key in the dictionary.
Once parsed you access the info via the dictionary's keys
Info info = rootObject.MoreInfo["info193802"];
Newtonsoft can correctly parse the data. The data represents objects, they happen to be nested fairly deep. You can accomplish it a couple of ways, for instance:
dynamic json = JsonConvert.DeserializeObject(response);
var info = json["moreinfo:info913802:example"].Value;
Your other option would be to use Visual Studio, let it create an object you can deserialize to.
Edit
Paste Special
As JSON
Output would be:
public class Rootobject
{
public string id { get; set; }
public Moreinfo moreInfo { get; set; }
}
public class Moreinfo
{
public Info193802 info193802 { get; set; }
public Info920938 info920938 { get; set; }
public Info849028 info849028 { get; set; }
}
public class Info193802
{
public string Example { get; set; }
}
public class Info920938
{
public string Example { get; set; }
}
public class Info849028
{
public string Example { get; set; }
}
The source JSON I used was yours, with one exception:
{ "id": "983f90j30909j3f",
"moreInfo": {
"info193802": { "Example" : "Blah" },
"info920938": { "Example" : "Blah" },
"info849028": {"Example" : "Blah" }
}
}

Object to json convertion format using serializer

I have the following c# model object
public class AddressUserFields
{
public string number { get; set; }
public string street { get; set; }
public string apartment { get; set; }
public string city { get; set; }
public string state { get; set; }
public string zipcode { get; set; }
public string DPV { get; set; }
}
When I am trying to convert it to json string using json serialization method, it will convert like the following,
JSON string: {userFields:[{"number":null,"street":null,"apartment":"","city":null,"state":null,"zipcode":null,"DPV":null}]}
But actually I look for like the below,
Expected JSON result:
{userFields:[{"number":null},{"street":null},{"apartment":""},{"city":null},{"state":null},{"zipcode":null},{"DPV":null}]}
So could any one give the way to design my c# model object and get the expected json result.
You just have to create your poco objects in the structure your want the Json to be in.
If you want this structure:
{userFields:
[
{ "number":null,
"street":null,
"apartment":"",
"city":null,
"state":nul‌​l,
"zipcode":null,
"DPV":null
}
]
}
This is an object with one property userFields of type AddressUserFields[].
So just add another class
public class SomeContainer
{
public AddressUserFields[] userFields {get;set;}
}
and serialize that one
If you really want an array of different objects which all have different properties, like what you posted:
...[{"number":null},{"street":null},{"apartment":""},...]
you can use an array of Dictionary<TKey,TValue>, like this:
public class Fields
{
public Dictionary<string, string>[] userFields { get; set; }
}
and use it like so?
var fields = new Fields()
{
userFields = new[]{
new Dictionary<string,string>(){{"number", null}},
new Dictionary<string,string>(){{"street", null}}
}
};
var json = JsonConvert.SerializeObject(fields);

Categories

Resources