I have following JSON that I'm writing object model to deserialize into:
{
"company_webhooks": [
{
"company_webhook": {
"id": 42,
"url": "https://keeptruckin.com/callbacktest/842b02",
"secret": "fe8b75de0a4e5898f0011faeb8c93654",
"format": "json",
"actions": [
"vehicle_location_received",
"vehicle_location_updated"
],
"enabled": false
}
},
{
"company_webhook": {
"id": 43,
"url": "https://keeptruckin.com/callbacktest/a6a783",
"secret": "66a7368063cb21887f546c7af91be59c",
"format": "json",
"actions": [
"vehicle_location_received",
"vehicle_location_updated"
],
"enabled": false
}
},
{
"company_webhook": {
"id": 44,
"url": "https://keeptruckin.com/callbacktest/53a52c",
"secret": "4451dc96513b3a67107466dd2c4d9589",
"format": "json",
"actions": [
"vehicle_location_received",
"vehicle_location_updated"
],
"enabled": false
}
},
{
"company_webhook": {
"id": 45,
"url": "https://keeptruckin.com/callbacktest/6fb337",
"secret": "4177fbd88c30faaee03a4362648bd663",
"format": "json",
"actions": [
"vehicle_location_received",
"vehicle_location_updated"
],
"enabled": false
}
},
{
"company_webhook": {
"id": 46,
"url": "https://keeptruckin.com/callbacktest/8cd6da",
"secret": "6e41817a048b009435e5102fca17db55",
"format": "json",
"actions": [
"vehicle_location_received",
"vehicle_location_updated"
],
"enabled": false
}
}
],
"pagination": {
"per_page": 25,
"page_no": 1,
"total": 5
}
}
Here is what I have:
[DataContract]
public class KeepTruckinResponse
{
[DataMember(Name = "company_webhooks", EmitDefaultValue = false)]
public KeepTruckinCompanyWebHook[] WebHooks { get; set; }
[DataMember(Name = "pagination", EmitDefaultValue = false)]
public KeepTruckinPagination Pagination { get; set; }
public string RawJSON { get; set; }
}
[DataContract]
public class KeepTruckinPagination
{
[DataMember(Name = "per_page", EmitDefaultValue = false)]
public int PerPage { get; set; }
[DataMember(Name = "page_no", EmitDefaultValue = false)]
public int PageNumber { get; set; }
[DataMember(Name = "total", EmitDefaultValue = false)]
public int Total { get; set; }
}
[DataContract(Name = "company_webhook")]
public class KeepTruckinCompanyWebHook
{
[DataMember(Name = "id", EmitDefaultValue = false)]
public int Id { get; set; }
[DataMember(Name = "url", EmitDefaultValue = false)]
public string Url { get; set; }
}
Obviously, when I deserialize JSON I don't get KeepTruckinCompanyWebHook properties because the way they send collection is "nested". I almost have to create another object inside KeepTruckinCompanyWebHook with properties. But I'd like to keep my object model as it is. Is it possible with .NET serializer?
We use DataContractJsonSerializer like so:
var ser = new DataContractJsonSerializer(typeof(KeepTruckinResponse));
response = ser.ReadObject(ms) as KeepTruckinResponse;
At this point we don't want to use NewtonSoft.Json
Yes, this is possible, but you will need some custom code to do it.
It's a little ugly, but you can create a custom IDataContractSurrogate class to deserialize each JSON object inside the company_webhooks array into a Dictionary<string, Dictionary<string, object>>, and then copy the values from the nested dictionary structure into an instance of your KeepTruckinCompanyWebHook class. Here's the code you would need for the surrogate:
class MyDataContractSurrogate : IDataContractSurrogate
{
public Type GetDataContractType(Type type)
{
if (type == typeof(KeepTruckinCompanyWebHook))
{
return typeof(Dictionary<string, Dictionary<string, object>>);
}
return type;
}
public object GetDeserializedObject(object obj, Type targetType)
{
if (obj.GetType() == typeof(Dictionary<string, Dictionary<string, object>>) &&
targetType == typeof(KeepTruckinCompanyWebHook))
{
var webHook = new KeepTruckinCompanyWebHook();
var outerDict = (Dictionary<string, Dictionary<string, object>>)obj;
var innerDict = outerDict["company_webhook"];
foreach (PropertyInfo prop in GetDataMemberProperties(typeof(KeepTruckinCompanyWebHook)))
{
DataMemberAttribute att = prop.GetCustomAttribute<DataMemberAttribute>();
object value;
if (innerDict.TryGetValue(att.Name, out value))
{
prop.SetValue(webHook, value);
}
}
return webHook;
}
return obj;
}
public object GetObjectToSerialize(object obj, Type targetType)
{
if (obj.GetType() == typeof(KeepTruckinCompanyWebHook) &&
targetType == typeof(Dictionary<string, Dictionary<string, object>>))
{
var webHook = (KeepTruckinCompanyWebHook)obj;
var outerDict = new Dictionary<string, Dictionary<string, object>>();
var innerDict = new Dictionary<string, object>();
outerDict.Add("company_webhook", innerDict);
foreach (PropertyInfo prop in GetDataMemberProperties(typeof(KeepTruckinCompanyWebHook)))
{
DataMemberAttribute att = prop.GetCustomAttribute<DataMemberAttribute>();
innerDict.Add(att.Name, prop.GetValue(webHook));
}
return outerDict;
}
return obj;
}
private IEnumerable<PropertyInfo> GetDataMemberProperties(Type type)
{
return type.GetProperties().Where(p => p.CanRead && p.CanWrite && p.GetCustomAttribute<DataMemberAttribute>() != null);
}
// ------- The rest of these methods do not need to be implemented -------
public object GetCustomDataToExport(Type clrType, Type dataContractType)
{
throw new NotImplementedException();
}
public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
{
throw new NotImplementedException();
}
public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes)
{
throw new NotImplementedException();
}
public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
{
throw new NotImplementedException();
}
public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
{
throw new NotImplementedException();
}
}
To use the surrogate, you'll need to create an instance of DataContractJsonSerializerSettings and pass it to the DataContractJsonSerializer with the following properties set. Note that since we require the UseSimpleDictionaryFormat setting, this solution will only work with .Net 4.5 or later.
var settings = new DataContractJsonSerializerSettings();
settings.DataContractSurrogate = new MyDataContractSurrogate();
settings.KnownTypes = new List<Type> { typeof(Dictionary<string, Dictionary<string, object>>) };
settings.UseSimpleDictionaryFormat = true;
Here is a demo:
public class Program
{
public static void Main(string[] args)
{
string json = #"
{
""company_webhooks"": [
{
""company_webhook"": {
""id"": 42,
""url"": ""https://keeptruckin.com/callbacktest/842b02"",
""secret"": ""fe8b75de0a4e5898f0011faeb8c93654"",
""format"": ""json"",
""actions"": [
""vehicle_location_received"",
""vehicle_location_updated""
],
""enabled"": false
}
},
{
""company_webhook"": {
""id"": 43,
""url"": ""https://keeptruckin.com/callbacktest/a6a783"",
""secret"": ""66a7368063cb21887f546c7af91be59c"",
""format"": ""json"",
""actions"": [
""vehicle_location_received"",
""vehicle_location_updated""
],
""enabled"": false
}
},
{
""company_webhook"": {
""id"": 44,
""url"": ""https://keeptruckin.com/callbacktest/53a52c"",
""secret"": ""4451dc96513b3a67107466dd2c4d9589"",
""format"": ""json"",
""actions"": [
""vehicle_location_received"",
""vehicle_location_updated""
],
""enabled"": false
}
},
{
""company_webhook"": {
""id"": 45,
""url"": ""https://keeptruckin.com/callbacktest/6fb337"",
""secret"": ""4177fbd88c30faaee03a4362648bd663"",
""format"": ""json"",
""actions"": [
""vehicle_location_received"",
""vehicle_location_updated""
],
""enabled"": false
}
},
{
""company_webhook"": {
""id"": 46,
""url"": ""https://keeptruckin.com/callbacktest/8cd6da"",
""secret"": ""6e41817a048b009435e5102fca17db55"",
""format"": ""json"",
""actions"": [
""vehicle_location_received"",
""vehicle_location_updated""
],
""enabled"": false
}
}
],
""pagination"": {
""per_page"": 25,
""page_no"": 1,
""total"": 5
}
}";
var settings = new DataContractJsonSerializerSettings();
settings.DataContractSurrogate = new MyDataContractSurrogate();
settings.KnownTypes = new List<Type> { typeof(Dictionary<string, Dictionary<string, object>>) };
settings.UseSimpleDictionaryFormat = true;
KeepTruckinResponse response = Deserialize<KeepTruckinResponse>(json, settings);
foreach (KeepTruckinCompanyWebHook wh in response.WebHooks)
{
Console.WriteLine("Id: " + wh.Id + ", Url: " + wh.Url);
}
}
public static T Deserialize<T>(string json, DataContractJsonSerializerSettings settings)
{
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
var ser = new DataContractJsonSerializer(typeof(T), settings);
return (T)ser.ReadObject(ms);
}
}
public static string Serialize(object obj, DataContractJsonSerializerSettings settings)
{
using (MemoryStream ms = new MemoryStream())
{
var ser = new DataContractJsonSerializer(obj.GetType(), settings);
ser.WriteObject(ms, obj);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
[DataContract]
public class KeepTruckinResponse
{
[DataMember(Name = "company_webhooks", EmitDefaultValue = false)]
public KeepTruckinCompanyWebHook[] WebHooks { get; set; }
[DataMember(Name = "pagination", EmitDefaultValue = false)]
public KeepTruckinPagination Pagination { get; set; }
public string RawJSON { get; set; }
}
[DataContract]
public class KeepTruckinPagination
{
[DataMember(Name = "per_page", EmitDefaultValue = false)]
public int PerPage { get; set; }
[DataMember(Name = "page_no", EmitDefaultValue = false)]
public int PageNumber { get; set; }
[DataMember(Name = "total", EmitDefaultValue = false)]
public int Total { get; set; }
}
[DataContract(Name = "company_webhook")]
public class KeepTruckinCompanyWebHook
{
[DataMember(Name = "id", EmitDefaultValue = false)]
public int Id { get; set; }
[DataMember(Name = "url", EmitDefaultValue = false)]
public string Url { get; set; }
}
Output:
Id: 42, Url: https://keeptruckin.com/callbacktest/842b02
Id: 43, Url: https://keeptruckin.com/callbacktest/a6a783
Id: 44, Url: https://keeptruckin.com/callbacktest/53a52c
Id: 45, Url: https://keeptruckin.com/callbacktest/6fb337
Id: 46, Url: https://keeptruckin.com/callbacktest/8cd6da
Related
I use NSwagStudio to create a C# client from an OpenAPI document.
So far everything works, but I noticed a problem to which I haven't found a solution yet.
The problem is that NSwagStudio creates duplicate classes for a recurring structure.
The following JSON as an example:
{
"components": {
"schemas": {
"Person": {
"type": "object",
"properties": {
"Id": {
"type": "string"
},
"Name": {
"type": "string"
},
"First Name": {
"type": "string"
},
"Lastname": {
"type": "string"
},
"attributes": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"url": {
"type": "string"
}
}
}
},
"description": "Account Object"
},
"Address": {
"type": "object",
"properties": {
"Id": {
"type": "string"
},
"Street": {
"type": "string"
},
"Post Code": {
"type": "string"
},
"City": {
"type": "string"
},
"Country": {
"type": "string"
},
"attributes": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"url": {
"type": "string"
}
}
}
},
"description": "Address Object"
}
}
}
}
Here are 2 simple objects described, Person and Address.
Both objects have this structure in common:
"attributes" : {
"type" : "object",
"properties" : {
"type" : {
"type" : "string"
},
"url" : {
"type" : "string"
}
}
}
In C#, the result looks like this:
public partial class Attributes
{
[Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Type { get; set; }
[Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Url { get; set; }
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
public string ToJson()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings());
}
public static Attributes FromJson(string data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<Attributes2>(data, new Newtonsoft.Json.JsonSerializerSettings());
}
}
public partial class Attributes2
{
[Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Type { get; set; }
[Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Url { get; set; }
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
public string ToJson()
{
return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings());
}
public static Attributes2 FromJson(string data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<Attributes2>(data, new Newtonsoft.Json.JsonSerializerSettings());
}
}
These attribute classes themselves are just helper classes for other classes.
In total over 700 of them were created.
Is it not possible to create only one class for this?
The path part of the OpenAPI document contains $ref references to the "main" object
{
"/Person": {
"description": "",
"get": {
"responses": {
"200": {
"description": "Status Code 200",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Person"
}
}
}
},
}
}
}
}
The C# class Person, which is specified by $ref (see above)
Here the getter/setter with Attributes372 class.
public partial class Person
{
[Newtonsoft.Json.JsonProperty("Id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Id { get; set; }
[Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string Name{ get; set; }
[Newtonsoft.Json.JsonProperty("LastName", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string LastName { get; set; }
[Newtonsoft.Json.JsonProperty("FirstName", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public string FirstName { get; set; }
[Newtonsoft.Json.JsonProperty("attributes", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public Attributes372 Attributes { get; set; }
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties; }
set { _additionalProperties = value; }
}
}
``
I believe I checked all the recursive JSON sections on here, none seem even recursive but whatever. I have a challenge. How do I iterate through all the depts of this JSON? This JSON has a depth of 200 and that's not even the biggest one.
The JSON "Recursive" is not even a true array, there's only 1 item.
{
"schema": [
{
"#id": 1,
"recursive": [
{
"#Id": 2,
"from": {
"#id": 1,
"recursive": [
{
"#Id": 2,
"from": {
"#id": 1,
"recursive": [
"#Id": 2,
"from" : 49
]
}
}
]
}
}
]
}
]
}
My Configuration classes
public class rootSchema
{
[JsonProperty("#id")]
public int #id { get; set; }
[JsonProperty("recursive")]
public List<recursive> recursive { get; set; }
}
public class from
{
[JsonProperty("#id")]
public int #id { get; set; }
[JsonProperty("recursive")]
public List<recursive> recursive { get; set; }
}
public class recursive
{
[JsonProperty("from")]
public from from { get; set; }
[JsonProperty("recursive")]
public List<recursive> recursive { get; set; }
}
When I attempt to deserialize this using NewtonSoft.JSON Deserializer, I get an int64 conversion error
Newtonsoft.Json.JsonSerializationException:
'Error converting value 49 to type 'Proj.recursive.from'. Path
'recursive[0].from.recursive[0].from.recursive[0].from.recursive[0]
.from.recursive[0].from.recursive[0].from.recursive[0].from.recursive[0]
.from.recursive[0].from.recursive[0].from.recursive[0].from.recursive[0]
.from.recursive[0].from.recursive[0].from.recursive[0].from.recursive[0]
.from.recursive[0].from.recursive[0].from.recursive[0].from.recursive[0]
.from.recursive[0].from.recursive[0].from.recursive[0].from.recursive[0]
.from.recursive[0].from', line 1, position 16273.'
I found the cause of this, because in the last element "from", its not a list, its an integer
"from": 49,
So I am not even sure how to account for a list, & and integer in my definitions. My second issue is, I'm not sure how to iterate through the recursion to get all the "recursive" elements.
Solved it. Im just going to leave this here
Defs
using Newtonsoft.Json;
using System.Collections.Generic;
namespace theHack
{
public class Root
{
[JsonProperty("ratsnest")]
public ratsnest ratsnest { get; set; }
}
public class ratsnest
{
[JsonProperty("garbagepile")]
public List<object> garbagepile { get; set; }
}
public class garbagepile
{
[JsonProperty("#id")]
public int #id { get; set; }
[JsonProperty("hammeredhotpoop")]
public List<object> hammeredhotpoop { get; set; }
}
public class hammeredhotpoop
{
[JsonProperty("#transitionId")]
public int #transitionId { get; set; }
[JsonProperty("nohumorleft")]
public object nohumorleft { get; set; }
}
public class outgoingTransitions
{
[JsonProperty("#transitionId")]
public int #transitionId { get; set; }
[JsonProperty("nohumorleft")]
public object nohumorleft { get; set; }
}
public class nohumorleft
{
[JsonProperty("#id")]
public int #id { get; set; }
[JsonProperty("hammeredhotpoop")]
public List<object> hammeredhotpoop { get; set; }
}
}
The "logic"... it compiles
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
namespace theHack
{
internal class Program
{
static void Main(string[] args)
{
string _data_file = GetFile();
// going normal, this is expected
Root root = JsonConvert.DeserializeObject<Root>(_data_file, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, MaxDepth = 200, NullValueHandling = NullValueHandling.Ignore });
// can only be 1 root state, everything goes downhill from here
var parent = root.ratsnest.garbagepile[0];
//strip all the stupid ids, must repeat this because any element can return any type
var parentSerialized = JsonConvert.SerializeObject(parent);
// begin the descent to only lord knows where
garbagepile handful = JsonConvert.DeserializeObject<garbagepile>(parentSerialized, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, MaxDepth = 200, NullValueHandling = NullValueHandling.Ignore });
// Can be integer or Jobject, who the heck knows, maybe a trainwreck managed to find its way here
List<object> incoming = handful.hammeredhotpoop;
foreach (var crap in incoming)
{
// whyyyyyyyyyyyyyyyy
if (crap.GetType() != typeof(int))
{
var rootOfEvil = JsonConvert.SerializeObject(crap);
// thank you James Newton King for making the longest constructor I've ever seen
hammeredhotpoop firstSeedOfEvil = JsonConvert.DeserializeObject<hammeredhotpoop>(rootOfEvil, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, MaxDepth = 200, NullValueHandling = NullValueHandling.Ignore });
Console.WriteLine($"#transitionId: {firstSeedOfEvil.transitionId}");
var firstHorseman = JsonConvert.SerializeObject(firstSeedOfEvil.nohumorleft);
nohumorleft forgotwhatIwasDoing = JsonConvert.DeserializeObject<nohumorleft>(firstHorseman, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, MaxDepth = 200, NullValueHandling = NullValueHandling.Ignore });
List<object> currentCrap = forgotwhatIwasDoing.hammeredhotpoop;
Console.WriteLine($"#id: {forgotwhatIwasDoing.#id}");
//loop
do
{
for (int i = 0; i < currentCrap.Count; i++)
{
//deserialize the List<object>
hammeredhotpoop omgIgiveup = updatemyresume(currentCrap[i]);
//output something
Console.WriteLine($"#transitionId: {omgIgiveup.transitionId}");
// create typed version from this current Transition
nohumorleft deserializedfirstHorseman = barreloflaughs(omgIgiveup.nohumorleft);
Console.WriteLine($"#id: {deserializedfirstHorseman.#id}");
//get the next set of incomingTansitions
currentCrap = deserializedfirstHorseman.hammeredhotpoop;
}
} while (currentCrap != null);
}
}
Console.ReadLine();
}
public static hammeredhotpoop updatemyresume(object garbageIn)
{
if (garbageIn.GetType() != typeof(int))
{
var hammerIt = JsonConvert.SerializeObject(garbageIn);
hammeredhotpoop garbageOut = JsonConvert.DeserializeObject<hammeredhotpoop>(hammerIt, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, MaxDepth = 200, NullValueHandling = NullValueHandling.Ignore });
return garbageOut;
}
else { return null; }
}
public static nohumorleft barreloflaughs(object garbageIn)
{
var hammerIt = JsonConvert.SerializeObject(garbageIn);
nohumorleft garbageOut = JsonConvert.DeserializeObject<nohumorleft>(hammerIt, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, MaxDepth = 200, NullValueHandling = NullValueHandling.Ignore });
return garbageOut;
}
public static string GetFile()
{
var fileName = #"C:\Users\me\source\test.json";
if (File.Exists(fileName))
{
using (StreamReader file = new StreamReader(fileName))
{
string text = File.ReadAllText(fileName);
file.Close();
return text;
}
}
else
{
Console.WriteLine("File does not exist");
return null;
}
}
}
}
a representation of the JSON
{
"ThisWasActuallyAnArray": [
{
"surprising": [
{
"typeNull": null,
"connectionId": "233ad541-7468-49b5-a7bb-dddddd",
"id": 29531,
"name": "funnyTown",
"letsEmbedSomeJson": "{\"id\":\"234\",..."
}
],
"type": "",
"id": 46243,
"name": "somestring"
}
],
"ratsnest": {
"whynot": null,
"garbagepile": [
{
"#id": 1,
"subData": null,
"subDataClass": "",
"id": "123-abc",
"hammeredhotpoop": [
{
"#transitionId": 4,
"datastuff": {
"abool": false,
"astring": "anyway",
"anInt": 1
},
"anotherRabbitHole2": 3,
"id": "123",
"name": "...",
"anotherRabbitHole": {
"#id": 5,
"someData": {
"setting1": true,
"Grouping": "FooBar",
"str1": "60",
"aBool": true,
"id": 5
},
"config": "somedata",
"id": "123",
"nohumorleft": {},
"name": "",
"notes": ""
},
"nohumorleft": {
"#id": 9,
"listData": {},
"id": "123",
"hammeredhotpoop": [
{
"#transitionId": 4,
"datastuff": {
"abool": false,
"astring": "anyway",
"anInt": 1
},
"anotherRabbitHole2": 3,
"id": "123",
"name": "...",
"anotherRabbitHole": {
"#id": 5,
"someData": {
"setting1": true,
"Grouping": "FooBar",
"str1": "60",
"aBool": true,
"id": 5
},
"config": "somedata",
"id": "123",
"nohumorleft": {},
"name": "",
"notes": ""
},
"nohumorleft": [
{
"#id": 9,
"listData": {},
"id": "123",
"hammeredhotpoop": [
{
"#transitionId": 4,
"datastuff": {
"abool": false,
"astring": "anyway",
"anInt": 1
},
"anotherRabbitHole2": 3,
"id": "123",
"name": "...",
"anotherRabbitHole": {
"#id": 5,
"someData": {
"setting1": true,
"Grouping": "FooBar",
"str1": "60",
"aBool": true,
"id": 5
},
"config": "somedata",
"id": "123",
"nohumorleft": {},
"name": "",
"notes": ""
},
"nohumorleft": {
"#id": 9,
"listData": {},
"id": "123",
"hammeredhotpoop": [
{
"#transitionId": 4,
"datastuff": {
"abool": false,
"astring": "anyway",
"anInt": 1
},
"anotherRabbitHole2": 3,
"id": "123",
"name": "...",
"anotherRabbitHole": {
"#id": 5,
"someData": {
"setting1": true,
"Grouping": "FooBar",
"str1": "60",
"aBool": true,
"id": 5
},
"config": "somedata",
"id": "123",
"name": "",
"notes": "",
"nohumorleft": 49
}
}
]
}
}
]
},
"3",
"2",
"1",
"upskill",
true
]
}
]
}
},
5,
4,
3,
2,
1,
"LOL"
],
"notes": "",
"someInt": 0,
"type": "",
"hammeredhotboogers": [],
"listData": {}
}
]
}
}
I'm having an object of Type Job, and I successfully serialized it into a JSON file, but I'm getting this problem
Could not cast or convert from System.String to
qConnector_v2._0.Model.Job
Here is how I'm doing the Serialization:
_Job.Tasks.Add(new Email());
_Job.Tasks.Add(new UNC());
_Job.Tasks.Add(new FTP());
_Job.Tasks.Add(new WebApi());
_Job.Tasks.Add(new WebService());
_Job.Tasks.Add(new StoredProcedure());
_Job.Tasks.Add(new Odbc());
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Converters.Add(new Newtonsoft.Json.Converters.JavaScriptDateTimeConverter());
serializer.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto;
serializer.Formatting = Newtonsoft.Json.Formatting.Indented;
using (StreamWriter sw = new StreamWriter(#"C:\Temp\res.json"))
using (Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter(sw))
{
serializer.Serialize(writer, _Job, typeof(Model.Job));
}
Here is how I'm doing the Deserialization:
Model.Job obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Model.Job>(File.ReadAllText(#"C:\Temp\res.json"), new Newtonsoft.Json.JsonSerializerSettings
{
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto,
});
For more details, here is the structure of the class:
Main Class - Job
class Job : IDisposable
{
private Guid _ID;
public Job()
{
ID = Guid.NewGuid();
}
public Guid ID { get { return _ID; } internal set { _ID = value; } }
public DateTime ScheduledTime { get; set; }
public Configurations Configuration { get; set; }
public Scheduler Scheduler { get; set; }
public List<Task> Tasks { get; set; }
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
~Job()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(false);
}
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
and here is the Task declaration, and I derived more Types if the this interface
public interface Task : IDisposable
{
//public Task() { }
string Title { get; set; }
bool ExecuteTask();/* { return true; }*/
bool? NotifyOnSuccess { get; set; }
bool? NotifyOnFailure { get; set; }
}
and here is the list of Types derived from Task interface:
Here is sample of the one of the classes derived from Task Type:
public class Email : Task
{
public string Recipients { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public string AttachmentPath { get; set; }
public string From { get; set; }
public string Title { get; set; }
public bool? NotifyOnSuccess { get; set; }
public bool? NotifyOnFailure { get; set; }
public void Dispose()
{
throw new NotImplementedException();
}
public bool ExecuteTask()
{
return true;
}
}
Here is the JSON output.
Note: the values of the fields in Scheduler class are assigned but I don't know why they're shown with different values in the output.
{
"ID": "9ebcec6c-8adb-421d-882b-da51b106f14b",
"ScheduledTime": new Date(
1536674974648
),
"Configuration": {
"CommunicationLanguage": 0,
"NotifyBy": 0,
"RelayServer": "Relay Server",
"Port": "Port",
"Username": "Username",
"Passwoprd": "Password",
"FromAddress": "From address",
"Recipients": "",
"StoredProcedureName": "Stored procedure name",
"ConnectionString": "Connection String",
"ProfileName": "Profile name"
},
"Scheduler": {
"ScheduleType": 0,
"Occurs": 0,
"RecursEvery": 1,
"OccursOnceAt": "17:04:47.3262587",
"DurationStartDate": new Date(
1536613487322
),
"DurationEndDate": new Date(
1536613487318
),
"dayOrderInMonth": 0,
"DayName": 0
},
"Tasks": [
{
"$type": "qConnector_v2._0.Model.WebApi, qConnector v2.0",
"BaseURL": "d",
"Route": "d",
"Params": "d",
"Header": "d",
"NotifyOnSuccess": true,
"NotifyOnFailure": false,
"Title": "api Test"
},
{
"$type": "qConnector_v2._0.Model.WebService, qConnector v2.0",
"Title": "ws test",
"Url": "",
"Name": "",
"Method": "",
"NotifyOnSuccess": true,
"NotifyOnFailure": false
},
{
"$type": "qConnector_v2._0.Model.Odbc, qConnector v2.0",
"Title": "odbc",
"DataSource": "Data source",
"Database": "Database",
"User": "Username",
"Password": "Password",
"Type": "Odbc Type",
"Query": "QUERY",
"DestinationDataSource": "Data source",
"DestinationDatabase": "Database",
"DestinationUsername": "Username",
"DestinationPassword": "Password",
"DestinationStoreProcedure": "Stored Procedure Name",
"DestinationLocation": "UNC Destination",
"NotifyOnSuccess": false,
"NotifyOnFailure": true
},
{
"$type": "qConnector_v2._0.Model.FTP, qConnector v2.0",
"Title": "ftp",
"LocalPath": "Local path",
"Server": "Server Path",
"Password": "Password",
"Username": "Username",
"Download": false,
"Upload": true,
"NotifyOnSuccess": true,
"NotifyOnFailure": false
},
{
"$type": "qConnector_v2._0.Model.Excel, qConnector v2.0",
"Title": "excel",
"Location": "UNC path to load Excel file",
"DataSource": "Data source",
"Database": "Database",
"Username": "Username",
"Password": "Password",
"StoredProcedure": "Stored Procedure Name",
"SheetName": "Sheet Name (optional)",
"NotifyOnSuccess": true,
"NotifyOnFailure": true
},
{
"$type": "qConnector_v2._0.Model.UNC, qConnector v2.0",
"Title": "unc test",
"Type": 2,
"Source": "Source Path",
"Destination": "Destination Path",
"NotifyOnSuccess": true,
"NotifyOnFailure": true
},
{
"$type": "qConnector_v2._0.Model.Email, qConnector v2.0",
"Recipients": "recipient email,recipient email,recipient email",
"Subject": "Subject",
"Body": "BODY",
"AttachmentPath": "Attachment Path",
"From": "From",
"Title": "email test",
"NotifyOnSuccess": false,
"NotifyOnFailure": true
},
{
"$type": "qConnector_v2._0.Model.StoredProcedure, qConnector v2.0",
"Title": "TITLE",
"NotifyOnSuccess": true,
"NotifyOnFailure": false,
"DataSource": "Data source",
"Database": "Database",
"Username": "Username",
"Password": "Password",
"SqlCommand": "SQL Command - SP Call"
}
]
}
Here is the structure of the Scheduler class:
public class Scheduler : IDisposable
{
public enum SchedulerType { Recurring, OneTime };
public enum SchedulerFrequency { Daily, Weekly, Monthly };
public enum DayOrderInMonth { First, Second, Third, Fourth, Last };
public DateTime? Scheduled { get; set; }
public SchedulerType ScheduleType { get; set; }
public DateTime? OneTimeDate { get; set; }
public TimeSpan? OneTimeTime { get; set; }
public SchedulerFrequency Occurs { get; set; }
public int? RecursEvery { get; set; }
public TimeSpan? OccursOnceAt { get; set; }
public DateTime? DurationStartDate { get; set; }
public DateTime? DurationEndDate { get; set; }
public string WeekDays { get; set; }
public List<DayOfWeek> WeekDaysList { get; set; }
public DayOrderInMonth dayOrderInMonth { get; set; }
public DayOfWeek DayName { get; set; }
public int? EveryNumberOfMonth { get; set; }
public int? DayNumberEachMonth { get; set; }
public int? TheOptionRecursEveryMonth { get; set; }
public int? RecursEveryWeek { get; set; }
}
The solution was very simple,
instead of using this
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Converters.Add(new Newtonsoft.Json.Converters.JavaScriptDateTimeConverter());
serializer.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto;
serializer.Formatting = Newtonsoft.Json.Formatting.Indented;
using (StreamWriter sw = new StreamWriter(#"C:\Temp\res.json"))
using (Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter(sw))
{
serializer.Serialize(writer, _Job, typeof(Model.Job));
}
I only had to remove the following line:
serializer.Converters.Add(new
Newtonsoft.Json.Converters.JavaScriptDateTimeConverter());
So the code will be:
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
serializer.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto;
serializer.Formatting = Newtonsoft.Json.Formatting.Indented;
using (StreamWriter sw = new StreamWriter(#"C:\Temp\res.json"))
using (Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter(sw))
{
serializer.Serialize(writer, _Job, typeof(Model.Job));
}
I'd like to convert into Json the following Dictionary type:
public class Repsonse
{
public Dictionary<Employee, List<Car>> Dictionary { get; set; }
public class Employee
{
public string Name { get; set; }
public string Id { get; set; }
public decimal Seniority { get; set; }
}
public class Car
{
public string OwnerId { get; set; }
public string Model { get; set; }
public string RegistrationPlate { get; set; }
}
}
I expect it to be serialized into the following Json:
{
"Dictionary": [
{
"Name": "John Doe",
"Seniority": "2",
"OwnerId": "1111"
"Cars": [
{
"OwnerId": "1111"
"Model": "Chevrolet Spark",
"RegistrationPlate": "LTO1234"
},
{
"OwnerId": "1111"
"Model": "Chevrolet Malibu",
"RegistrationPlate": "LTO5678"
}
]
},
{
"Name": "Jane Doe",
"Seniority": "10",
"OwnerId": "9999"
"Cars": [
{
"OwnerId": "9999"
"Model": "Mercedes Benz",
"RegistrationPlate": "ABC1234"
},
{
"OwnerId": "9999"
"Model": "Mercedes Maybach",
"RegistrationPlate": "ABC5678"
}
]
}
]
}
I'm using NewtonSoft Json for the serialization, and read that I need to use a TypeConverter to enable this kind of serialization, but it doesn't work for me.
Here's the TypeConverter implemenetation:
public class Employee : TypeConverter
{
public string Name { get; set; }
public string Id { get; set; }
public decimal Seniority { get; set; }
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return ((Employee)value).Name + "," + ((Employee)value).Id + "," + ((Employee)value).Seniority;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
You can see the full example code here.
How can I make it work?
The json output format that you have is for list not for dictionary. If you want to use dictionary may be you can follow below one
JSON Response
{
"Dictionary": {
"John Doe": {
"Name": "John Doe",
"Id": "1111",
"Seniority": 2,
"Cars": [
{
"OwnerId": "1111",
"Model": "Chevrolet Spark",
"RegistrationPlate": "LTO1234"
},
{
"OwnerId": "1111",
"Model": "Chevrolet Malibu",
"RegistrationPlate": "LTO5678"
}
]
},
"Jane Doe": {
"Name": "Jane Doe",
"Id": "9999",
"Seniority": 10,
"Cars": [
{
"OwnerId": "9999",
"Model": "Mercedes Benz",
"RegistrationPlate": "ABC1234"
},
{
"OwnerId": "9999",
"Model": "Mercedes Maybach",
"RegistrationPlate": "ABC5678"
}
]
}
}
}
and code will be
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
Response res = new Response { Dictionary = new Dictionary<string, Employee>() };
Employee firstEmployee = new Employee { Name = "John Doe", Id = "1111", Seniority = 2 };
Employee secondEmployee = new Employee { Name = "Jane Doe", Id = "9999", Seniority = 10 };
firstEmployee.Cars.Add(new Car { OwnerId = "1111", Model = "Chevrolet Spark", RegistrationPlate = "LTO1234" });
firstEmployee.Cars.Add(new Car { OwnerId = "1111", Model = "Chevrolet Malibu", RegistrationPlate = "LTO5678" });
secondEmployee.Cars.Add(new Car { OwnerId = "9999", Model = "Mercedes Benz", RegistrationPlate = "ABC1234" });
secondEmployee.Cars.Add(new Car { OwnerId = "9999", Model = "Mercedes Maybach", RegistrationPlate = "ABC5678" });
res.Dictionary.Add(firstEmployee.Name, firstEmployee);
res.Dictionary.Add(secondEmployee.Name, secondEmployee);
var result = JsonConvert.SerializeObject(res);
Console.WriteLine(result);
}
}
public class Response
{
public Dictionary<string, Employee> Dictionary { get; set; }
public class Employee : TypeConverter
{
public Employee(string name, decimal seniority, string id, List<Car> cars)
{
Name = name;
Seniority = seniority;
Id = id;
Cars = cars;
Cars = new List<Car>();
}
public Employee()
{
Cars = new List<Car>();
}
public string Name { get; set; }
public string Id { get; set; }
public decimal Seniority { get; set; }
public List<Car> Cars { get; set; }
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return ((Employee)value).Name + "," + ((Employee)value).Id + "," + ((Employee)value).Seniority;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
public class Car
{
public string OwnerId { get; set; }
public string Model { get; set; }
public string RegistrationPlate { get; set; }
}
}
I have to submit this JSON exactly or it does not work. While I was able to create most of it with the help of another member I cannot find information on dealing with nulls. When it submits the null value it will not run through the api.
Here is the JSON I must create
{
"resourceType": "Bundle",
"type": "message",
"entry": [
{
"resource": {
"resourceType": "MessageHeader",
"timestamp": "2016-12-29T08:00:00-07:00",
"id": "Test1",
"event":
{ "code": "diagnosticreport-provide" },
"source":
{ "endpoint": "http://yourdomain.com/api" },
"destination": [
{ "endpoint": "https://api.com/api/$process-message" }
]
}
},
{
"resource": {
"resourceType" : "DiagnosticReport",
"extension" : [{
"url" : "DiagnosticReportDefinition",
"extension" : [
{ "url" : "useNewMedications", "valueBoolean": "false" },
{ "url" : "providePDFReport", "valueBoolean": "false" },
{ "url" : "returnDetectedIssues", "valueBoolean": "true" },
{ "url" : "returnObservations", "valueBoolean": "true" },
{ "url" : "returnMedications", "valueBoolean": "true" },
{ "url" : "returnDosingGuidance", "valueBoolean": "true" },
{ "url" : "includePIMTable", "valueBoolean": "true" },
{ "url" : "includeDDIData", "valueBoolean": "false" },
{ "url" : "reportId", "valueString": "" }
]
}]
}
},
{
"resource":{
"resourceType": "ProcedureRequest",
"id": "17"
}
}]
}
Here is the code where I tried to do it and came close but having problems with nulls and one comma between the resources
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var obj = new RootReq()
{resourceType = "Bundle", type = "message", entry = new Entry[]{new Entry()
{resource = new Resource()
{resourceType = "MessageHeader", timestamp = DateTime.Now, id = "Test1", _event = new Event()
{code = "diagnosticreport-provide"}, source = new Source()
{endpoint = "http://yourdomain.com/api"}, destination = new Destination[]{new Destination()
{endpoint = "https://api.pgxportal.com/api/$process-message"}}}}, new Entry()
{resource = new Resource()
{resourceType = "DiagnosticReport", extension = new Extension[]{new Extension()
{url = "DiagnosticReportDefinition", extension = new Extension1[]{new Extension1()
{url = "useNewMedications", valueBoolean = "false"}, new Extension1()
{url = "providePDFReport", valueBoolean = "false"}, new Extension1()
{url = "returnDetectedIssues", valueBoolean = "true"}, new Extension1()
{url = "returnObservations", valueBoolean = "true"}, new Extension1()
{url = "returnMedications", valueBoolean = "true"}, new Extension1()
{url = "returnDosingGuidance", valueBoolean = "true"}, new Extension1()
{url = "includePIMTable", valueBoolean = "true"}, new Extension1()
{url = "includeDDIData", valueBoolean = "false"}, new Extension1()
{url = "reportId", valueString = ""}, }}}}}, new Entry()
{resource = new Resource()
{resourceType = "ProcedureRequest", id = "17"}}}};
var str = JsonConvert.SerializeObject(obj, Formatting.Indented);
Console.WriteLine(str);
}
}
public class RootReq
{
public string resourceType
{
get;
set;
}
public string type
{
get;
set;
}
public Entry[] entry
{
get;
set;
}
}
public class Entry
{
public Resource resource
{
get;
set;
}
}
public class Resource
{
public string resourceType
{
get;
set;
}
public DateTime timestamp
{
get;
set;
}
public string id
{
get;
set;
}
public Event _event
{
get;
set;
}
public Source source
{
get;
set;
}
public Destination[] destination
{
get;
set;
}
public Extension[] extension
{
get;
set;
}
}
public class Event
{
public string code
{
get;
set;
}
}
public class Source
{
public string endpoint
{
get;
set;
}
}
public class Destination
{
public string endpoint
{
get;
set;
}
}
public class Extension
{
public string url
{
get;
set;
}
public Extension1[] extension
{
get;
set;
}
}
public class Extension1
{
public string url
{
get;
set;
}
public string valueBoolean
{
get;
set;
}
public string valueString
{
get;
set;
}
}
Here it what the wrong json that this code is producing looks like
{
"resourceType": "Bundle",
"type": "message",
"entry": [
{
"resource": {
"resourceType": "MessageHeader",
"timestamp": "2017-05-24T06:45:36.0632742+00:00",
"id": "Test1",
"_event": {
"code": "diagnosticreport-provide"
},
"source": {
"endpoint": "http://yourdomain.com/api"
},
"destination": [
{
"endpoint": "https://api.pgxportal.com/api/$process-message"
}
],
"extension": null
}
},
{
"resource": {
"resourceType": "DiagnosticReport",
"timestamp": "0001-01-01T00:00:00",
"id": null,
"_event": null,
"source": null,
"destination": null,
"extension": [
{
"url": "DiagnosticReportDefinition",
"extension": [
{
"url": "useNewMedications",
"valueBoolean": "false",
"valueString": null
},
{
"url": "providePDFReport",
"valueBoolean": "false",
"valueString": null
},
{
"url": "returnDetectedIssues",
"valueBoolean": "true",
"valueString": null
},
{
"url": "returnObservations",
"valueBoolean": "true",
"valueString": null
},
{
"url": "returnMedications",
"valueBoolean": "true",
"valueString": null
},
{
"url": "returnDosingGuidance",
"valueBoolean": "true",
"valueString": null
},
{
"url": "includePIMTable",
"valueBoolean": "true",
"valueString": null
},
{
"url": "includeDDIData",
"valueBoolean": "false",
"valueString": null
},
{
"url": "reportId",
"valueBoolean": null,
"valueString": ""
}
]
}
]
}
},
{
"resource": {
"resourceType": "ProcedureRequest",
"timestamp": "0001-01-01T00:00:00",
"id": "17",
"_event": null,
"source": null,
"destination": null,
"extension": null
}
}
]
}
Try this:
var str= JsonConvert.SerializeObject(obj,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
Working now
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var obj = new RootReq()
{resourceType = "Bundle", type = "message", entry = new Entry[]{new Entry()
{resource = new Resource()
{resourceType = "MessageHeader",
timestamp = Convert.ToString(DateTime.Now),
id = "Test1",
_event = new Event()
{code = "diagnosticreport-provide"}, source = new Source()
{endpoint = "http://yourdomain.com/api"}, destination = new Destination[]{new Destination()
{endpoint = "https://api.com/api/$process-message"}}}}, new Entry()
{resource = new Resource()
{resourceType = "DiagnosticReport",
timestamp = null,
extension = new Extension[]{
new Extension()
{url = "DiagnosticReportDefinition", extension = new Extension1[]{new Extension1()
{url = "useNewMedications", valueBoolean = "false"}, new Extension1()
{url = "providePDFReport", valueBoolean = "false"}, new Extension1()
{url = "returnDetectedIssues", valueBoolean = "true"}, new Extension1()
{url = "returnObservations", valueBoolean = "true"}, new Extension1()
{url = "returnMedications", valueBoolean = "true"}, new Extension1()
{url = "returnDosingGuidance", valueBoolean = "true"}, new Extension1()
{url = "includePIMTable", valueBoolean = "true"}, new Extension1()
{url = "includeDDIData", valueBoolean = "false"}, new Extension1()
{url = "reportId", valueString = ""}, }}}}}, new Entry()
{resource = new Resource()
{resourceType = "ProcedureRequest", id = "17"}}}};
var str = JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore
});
Console.WriteLine(str);
}
}
public class RootReq
{
public string resourceType
{
get;
set;
}
public string type
{
get;
set;
}
public Entry[] entry
{
get;
set;
}
}
public class Entry
{
public Resource resource
{
get;
set;
}
}
public class Resource
{
public string resourceType
{
get;
set;
}
public String timestamp
{
get;
set;
}
public string id
{
get;
set;
}
public Event _event
{
get;
set;
}
public Source source
{
get;
set;
}
public Destination[] destination
{
get;
set;
}
public Extension[] extension
{
get;
set;
}
}
public class Event
{
public string code
{
get;
set;
}
}
public class Source
{
public string endpoint
{
get;
set;
}
}
public class Destination
{
public string endpoint
{
get;
set;
}
}
public class Extension
{
public string url
{
get;
set;
}
public Extension1[] extension
{
get;
set;
}
}
public class Extension1
{
public string url
{
get;
set;
}
public string valueBoolean
{
get;
set;
}
public string valueString
{
get;
set;
}
}