I have a json with different kind of blocks in it. There are simple block, like text, there's no problems in deserializing them, so I won't cover them up. The problems are with three kind of blocks: media, list and quiz:
{
"blocks": [
{
"type": "text",
"data": {
"text": "my awesome text",
"text_truncated": "<<<same>>>"
},
"cover": false,
"anchor": ""
},
{
"type": "media",
"data": {
"items": [
{
"title": "title1",
"author": "author1",
"image": {
"type": "image",
"data": {
"uuid": "eb19f678-3c9f-58f0-90c2-33bcb8237b17",
"width": 1024,
"height": 756,
"size": 448952,
"type": "jpg",
"color": "d3c58f",
"hash": "",
"external_service": []
}
}
},
{
"title": "title2",
"author": "author2",
"image": {
"type": "image",
"data": {
"uuid": "9274038e-1e9b-5cab-9db5-4936ce88a5c9",
"width": 750,
"height": 563,
"size": 164261,
"type": "jpg",
"color": "b7a58d",
"hash": "",
"external_service": []
}
}
}
],
"with_background": false,
"with_border": false
},
"cover": false,
"anchor": ""
},
{
"type": "list",
"data": {
"items": [
"foo",
"bar"
],
"type": "UL"
},
"cover": false,
"anchor": ""
},
{
"type": "quiz",
"data": {
"uid": "00bde249ff735f481620328765695",
"hash": "29d6bf8fec36eee3",
"tmp_hash": "",
"title": "When?",
"items": {
"a16203287650": "Ashita",
"a16203287651": "Kinou",
"a16203287742": "Ima"
},
"is_public": false,
"date_created": 1620328765
},
"cover": false,
"anchor": ""
}
]
}
These blocks's items property is different from one to another.
For serializing/deserializing I'm using System.Text.Json, built in net5.0. While I can deserialize this json's items into JsonElement and work with it further, I'd like to deserialize them to exact classes automatically, when I call JsonSerializer.Deserialize(...); e.g. IEnumerable<MediaBlockData>, IEnumerable<string> and so on, depending on what type (I mean json's property) it is.
While looking for answer I found out an article on mircosoft website, but I'm not wholly understand on how to implement it for my case:
https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-5-0
Update 1
My blocks implementation:
public class Block
{
[JsonPropertyName("type")]
public string Type { get; set; }
[JsonPropertyName("data")]
public JsonElement Data { get; set; }
public IBlockData ParsedData { get; set; }
[JsonPropertyName("cover")]
public bool Cover { get; set; }
[JsonPropertyName("anchor")]
public string Anchor { get; set; }
private Type GetBlockDataType() => Type switch
{
"audio" => typeof(AudioBlockData),
"code" => typeof(CodeBlockData),
"delimiter" => typeof(DelimiterBlockData),
"header" => typeof(HeaderBlockData),
"image" => typeof(ImageBlockData),
"incut" => typeof(IncutBlockData),
"instagram" => typeof(InstagramBlockData),
"link" => typeof(LinkBlockData),
"list" => typeof(ListBlockData),
"media" => typeof(MediaBlockData),
"number" => typeof(NumberBlockData),
"person" => typeof(PersonBlockData),
"quiz" => typeof(QuizBlockData),
"quote" => typeof(QuoteBlockData),
"spotify" => typeof(SpotifyBlockData),
"telegram" => typeof(TelegramBlockData),
"text" => typeof(TextBlockData),
"tiktok" => typeof(TikTokBlockData),
"tweet" => typeof(TweetBlockData),
"universalbox" => typeof(UniversalBoxBlockData),
"video" => typeof(VideoBlockData),
"yamusic" => typeof(YaMusicBlockData),
_ => typeof(object)
};
public IBlockData GetBlockData()
{
var blockType = GetBlockDataType();
return (IBlockData)JsonSerializer.Deserialize(Data.ToString(), blockType);
}
}
public class ListBlockData : IBlockData
{
[JsonPropertyName("items")]
public IEnumerable<string> Items { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; }
}
public class QuizBlockData : IBlockData
{
[JsonPropertyName("uid")]
public string Uid { get; set; }
[JsonPropertyName("hash")]
public string Hash { get; set; }
[JsonPropertyName("tmp_hash")]
public string TempHash { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("items")]
public JsonElement Items { get; set; }
[JsonPropertyName("is_public")]
public bool IsPublic { get; set; }
[JsonPropertyName("date_created")]
public long DateCreated { get; set; }
}
public class MediaBlockData : IBlockData
{
[JsonPropertyName("items")]
public IEnumerable<MediaItem> Items { get; set; }
[JsonPropertyName("with_background")]
public bool WithBackground { get; set; }
[JsonPropertyName("with_border")]
public bool WithBorder { get; set; }
}
public class MediaItem : Block
{
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("author")]
public string Author { get; set; }
[JsonPropertyName("image")]
public Block Image { get; set; }
}
Update 2
Here's minimal reproducable code sample with json string in it:
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ConsoleApp1
{
public interface IBlockData
{
}
public class TextBlockData : IBlockData
{
[JsonPropertyName("text")]
public string Text { get; set; }
[JsonPropertyName("text_truncated")]
public string TextTruncated { get; set; }
}
public class MediaItem : Block
{
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("author")]
public string Author { get; set; }
[JsonPropertyName("image")]
public Block Image { get; set; }
}
public class QuizBlockData : IBlockData
{
[JsonPropertyName("uid")]
public string Uid { get; set; }
[JsonPropertyName("hash")]
public string Hash { get; set; }
[JsonPropertyName("tmp_hash")]
public string TempHash { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("items")]
public JsonElement Items { get; set; } // TODO: normal class instead of JsonElement
[JsonPropertyName("is_public")]
public bool IsPublic { get; set; }
[JsonPropertyName("date_created")]
public long DateCreated { get; set; }
}
public class MediaBlockData : IBlockData
{
[JsonPropertyName("items")]
public IEnumerable<MediaItem> Items { get; set; }
[JsonPropertyName("with_background")]
public bool WithBackground { get; set; }
[JsonPropertyName("with_border")]
public bool WithBorder { get; set; }
}
public class ListBlockData : IBlockData
{
[JsonPropertyName("items")]
public IEnumerable<string> Items { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; }
}
public class ImageBlockData : IBlockData
{
[JsonPropertyName("uuid")]
public Guid Uuid { get; set; }
[JsonPropertyName("width")]
public int Width { get; set; }
[JsonPropertyName("height")]
public int Height { get; set; }
[JsonPropertyName("size")]
public long Size { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; }
[JsonPropertyName("color")]
public string Color { get; set; }
[JsonPropertyName("hash")]
public string Hash { get; set; }
[JsonPropertyName("external_service")]
public IEnumerable<ExternalService> ExternalService { get; set; }
}
public class ExternalService
{
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
}
public class Block
{
[JsonPropertyName("type")]
public string Type { get; set; }
[JsonPropertyName("data")]
public JsonElement Data { get; set; }
public IBlockData ParsedData { get; set; }
[JsonPropertyName("cover")]
public bool Cover { get; set; }
[JsonPropertyName("anchor")]
public string Anchor { get; set; }
private Type GetBlockDataType() => Type switch
{
"image" => typeof(ImageBlockData),
"list" => typeof(ListBlockData),
"media" => typeof(MediaBlockData),
"quiz" => typeof(QuizBlockData),
"text" => typeof(TextBlockData),
_ => typeof(object)
};
public IBlockData GetBlockData()
{
var blockType = GetBlockDataType();
return (IBlockData)JsonSerializer.Deserialize(Data.ToString(), blockType);
}
}
public class Root
{
[JsonPropertyName("blocks")]
public IEnumerable<Block> Blocks { get; set; }
}
internal static class Program
{
private static void Main()
{
var json = "{\"blocks\":[{\"type\":\"text\",\"data\":{\"text\":\"my awesome text\",\"text_truncated\":\"<<<same>>>\"},\"cover\":false,\"anchor\":\"\"},{\"type\":\"media\",\"data\":{\"items\":[{\"title\":\"title1\",\"author\":\"author1\",\"image\":{\"type\":\"image\",\"data\":{\"uuid\":\"eb19f678-3c9f-58f0-90c2-33bcb8237b17\",\"width\":1024,\"height\":756,\"size\":448952,\"type\":\"jpg\",\"color\":\"d3c58f\",\"hash\":\"\",\"external_service\":[]}}},{\"title\":\"title2\",\"author\":\"author2\",\"image\":{\"type\":\"image\",\"data\":{\"uuid\":\"9274038e-1e9b-5cab-9db5-4936ce88a5c9\",\"width\":750,\"height\":563,\"size\":164261,\"type\":\"jpg\",\"color\":\"b7a58d\",\"hash\":\"\",\"external_service\":[]}}}],\"with_background\":false,\"with_border\":false},\"cover\":false,\"anchor\":\"\"},{\"type\":\"list\",\"data\":{\"items\":[\"foo\",\"bar\"],\"type\":\"UL\"},\"cover\":false,\"anchor\":\"\"},{\"type\":\"quiz\",\"data\":{\"uid\":\"00bde249ff735f481620328765695\",\"hash\":\"29d6bf8fec36eee3\",\"tmp_hash\":\"\",\"title\":\"When?\",\"items\":{\"a16203287650\":\"Ashita\",\"a16203287651\":\"Kinou\",\"a16203287742\":\"Ima\"},\"is_public\":false,\"date_created\":1620328765},\"cover\":false,\"anchor\":\"\"}]}";
var root = JsonSerializer.Deserialize<Root>(json);
// Example on how it can be deserialized afterwards
foreach (Block block in root.Blocks)
{
block.ParsedData = block.GetBlockData();
}
}
}
}
Update 3
I've been able to deserialize blocks correctly (hope there are no major issues with this code), thanks to #dbc and this post:
Deserialize JSON array which has mixed values System.Text.JSON
Updated code:
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ConsoleApp1
{
public class BlockData
{
}
public class TextBlockData : BlockData
{
[JsonPropertyName("text")]
public string Text { get; set; }
[JsonPropertyName("text_truncated")]
public string TextTruncated { get; set; }
}
public class MediaItemBlock : Block
{
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("author")]
public string Author { get; set; }
[JsonPropertyName("image")]
public Block Image { get; set; }
}
public class QuizBlockData : BlockData
{
[JsonPropertyName("uid")]
public string Uid { get; set; }
[JsonPropertyName("hash")]
public string Hash { get; set; }
[JsonPropertyName("tmp_hash")]
public string TempHash { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("items")]
public Dictionary<string, string> Items { get; set; }
[JsonPropertyName("is_public")]
public bool IsPublic { get; set; }
[JsonPropertyName("date_created")]
public long DateCreated { get; set; }
}
public class MediaBlockData : BlockData
{
[JsonPropertyName("items")]
public IEnumerable<MediaItemBlock> Items { get; set; }
[JsonPropertyName("with_background")]
public bool WithBackground { get; set; }
[JsonPropertyName("with_border")]
public bool WithBorder { get; set; }
}
public class ListBlockData : BlockData
{
[JsonPropertyName("items")]
public IEnumerable<string> Items { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; }
}
public class ImageBlockData : BlockData
{
[JsonPropertyName("uuid")]
public Guid Uuid { get; set; }
[JsonPropertyName("width")]
public int Width { get; set; }
[JsonPropertyName("height")]
public int Height { get; set; }
[JsonPropertyName("size")]
public long Size { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; }
[JsonPropertyName("color")]
public string Color { get; set; }
[JsonPropertyName("hash")]
public string Hash { get; set; }
[JsonPropertyName("external_service")]
public IEnumerable<ExternalService> ExternalService { get; set; }
}
public class ExternalService
{
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
}
public class Block
{
[JsonPropertyName("type")]
public string Type { get; set; }
[JsonPropertyName("data")]
public BlockData Data { get; set; }
[JsonPropertyName("cover")]
public bool Cover { get; set; }
[JsonPropertyName("anchor")]
public string Anchor { get; set; }
public static Type GetBlockDataType(string type) => type switch
{
"image" => typeof(ImageBlockData),
"list" => typeof(ListBlockData),
"media" => typeof(MediaBlockData),
"quiz" => typeof(QuizBlockData),
"text" => typeof(TextBlockData),
_ => typeof(object)
};
}
public class Root
{
[JsonPropertyName("blocks")]
public IEnumerable<Block> Blocks { get; set; }
}
internal static class Program
{
private static void Main()
{
var json = "{\"blocks\":[{\"type\":\"text\",\"data\":{\"text\":\"my awesome text\",\"text_truncated\":\"<<<same>>>\"},\"cover\":false,\"anchor\":\"\"},{\"type\":\"media\",\"data\":{\"items\":[{\"title\":\"title1\",\"author\":\"author1\",\"image\":{\"type\":\"image\",\"data\":{\"uuid\":\"eb19f678-3c9f-58f0-90c2-33bcb8237b17\",\"width\":1024,\"height\":756,\"size\":448952,\"type\":\"jpg\",\"color\":\"d3c58f\",\"hash\":\"\",\"external_service\":[]}}},{\"title\":\"title2\",\"author\":\"author2\",\"image\":{\"type\":\"image\",\"data\":{\"uuid\":\"9274038e-1e9b-5cab-9db5-4936ce88a5c9\",\"width\":750,\"height\":563,\"size\":164261,\"type\":\"jpg\",\"color\":\"b7a58d\",\"hash\":\"\",\"external_service\":[]}}}],\"with_background\":false,\"with_border\":false},\"cover\":false,\"anchor\":\"\"},{\"type\":\"list\",\"data\":{\"items\":[\"foo\",\"bar\"],\"type\":\"UL\"},\"cover\":false,\"anchor\":\"\"},{\"type\":\"quiz\",\"data\":{\"uid\":\"00bde249ff735f481620328765695\",\"hash\":\"29d6bf8fec36eee3\",\"tmp_hash\":\"\",\"title\":\"When?\",\"items\":{\"a16203287650\":\"Ashita\",\"a16203287651\":\"Kinou\",\"a16203287742\":\"Ima\"},\"is_public\":false,\"date_created\":1620328765},\"cover\":false,\"anchor\":\"\"}]}";
var options = new JsonSerializerOptions
{
Converters = { new BlockConverter() }
};
var root = JsonSerializer.Deserialize<Root>(json, options);
var ser = JsonSerializer.Serialize(root, options);
}
}
public class BlockConverter : JsonConverter<Block>
{
public override Block Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using JsonDocument doc = JsonDocument.ParseValue(ref reader);
// Get type for convert
string type = doc.RootElement.GetProperty("type").GetString();
// Create new block with default deserializer
Block block = JsonSerializer.Deserialize<Block>(doc.RootElement.GetRawText());
// Warning: recursive for types with blocks inside
block.Data = (BlockData)JsonSerializer.Deserialize(doc.RootElement.GetProperty("data").GetRawText(),
Block.GetBlockDataType(type), options);
return block;
}
public override void Write(Utf8JsonWriter writer, Block value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
}
Now I'm trying to serialize it back to string correctly, not yet happening.
Here's a version that desieralises this json without using a converter.
var media = new List<MediaBlock>();
var texts = new List<TextBlock>();
using var doc = JsonDocument.Parse(json);
foreach (var block in doc.RootElement.GetProperty("blocks").EnumerateArray())
{
switch (block.GetProperty("type").GetString())
{
case "text": texts.Add(Deserialise<TextBlock>(block.GetProperty("data"))); break;
case "media": media.Add(Deserialise<MediaBlock>(block.GetProperty("data"))); break;
// ...
}
}
var composite = new
{
Texts = texts,// compsite.Texts[0].Text is 'my awesome text'
Media = media // compsite.Media.Items[0].Author is 'author1'
};
// This is OK, but if you need speed, please have a look at
// https://stackoverflow.com/questions/58138793/system-text-json-jsonelement-toobject-workaround
static T Deserialise<T>(JsonElement e) => JsonSerializer.Deserialize<T>(e.GetRawText(), options: new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
The auxiliary classes I used are:
class MediaBlock
{
public List<MediaItem> Items { get; set; }
}
class MediaItem
{
public string Author { get; set; }
public string Title { get; set; }
// ...
}
class TextBlock
{
public string Text { get; set; }
}
I have a JSON API result that I processed thru an online JSON-to-C# structure program to create the class structure. I've used this many times for other projects. The JSON returned everything along with a public class RootObject that references both the status and payload segments of the returned values.
I am using ASP.NET C# library to deserialize the result JSON using JavaScriptSerializer:
var vlist = new JavaScriptSerializer().Deserialize<TestStruct>(result);
My data structure looks like this (it's pretty standard):
public class TestStruct
{
public class Status
{
public int statusCode { get; set; }
public int errorType { get; set; }
public int errorCode { get; set; }
public string errorMessage { get; set; }
}
public class Payload
{
public VehicleStatusRpt vehicleStatusRpt { get; set; }
}
public class VehicleStatusRpt
{
public string statusType { get; set; }
//public ReportDate reportDate { get; set; }
//public VehicleStatus vehicleStatus { get; set; }
}
public class RootObject
{
public Status status { get; set; }
public Payload payload { get; set; }
}
}
The full JSON Result I'm trying to parse using the class structure is:
{
"status": {
"statusCode": 0,
"errorType": 0,
"errorCode": 0,
"errorMessage": "Success with response body"
},
"payload": {
"vehicleSummary": [
{
"vin": "KNDJX3AE8E7000080",
"vehicleIdentifier": "000080",
"modelName": "SOUL EV",
"modelYear": "2015",
"nickName": "My SOUL",
"generation": 1,
"extColorCode": "1D",
"trim": "EV",
"imagePath": {
"imageName": "2015-soul_ev-ev-1d.png",
"imagePath": "/content/dam/kia/us/owners/image/vehicle/2015/soul_ev/ev/",
"imageType": "1",
"imageSize": {
"length": "100",
"width": "100",
"uom": 0
}
},
"enrollmentStatus": 1,
"fatcAvailable": 1,
"telematicsUnit": 1,
"fuelType": 4,
"colorName": "CLEAR WHITE",
"activationType": 1,
"mileage": "24410",
"dealerCode": "MOBISDLR1",
"mobileStore": [
{
"osType": 0,
"downloadURL": "https://itunes.apple.com/us/app/kia-access-with-uvo-link/id1280548773?mt=8",
"image": {
"imageName": "iosImage.png",
"imagePath": "/content/dam/kia/us/owners/image/common/app/",
"imageType": "2",
"imageSize": {
"length": "100",
"width": "100",
"uom": 0
}
}
},
{
"osType": 1,
"downloadURL": "https://play.google.com/store/apps/details?id=com.myuvo.link",
"image": {
"imageName": "androidImage.png",
"imagePath": "/content/dam/kia/us/owners/image/common/app/",
"imageType": "2",
"imageSize": {
"length": "100",
"width": "100",
"uom": 0
}
}
}
],
"supportedApp": {
"appType": "5",
"appImage": {
"imageName": "app-access.png",
"imagePath": "/content/dam/kia/us/owners/image/common/app/access/",
"imageType": "2",
"imageSize": {
"length": "100",
"width": "100",
"uom": 0
}
}
},
"supportAdditionalDriver": 0,
"customerType": 0,
"vehicleKey": "937db044-8328-4188-a3d2-68ac3b183752"
}
]
}
}
I run this thru json2csharp.com to get the structure (the sample above is an abbreviated 'test' only
The deserializer returns an error: Invalid JSON Primitive (starting with Payload)
I see examples of using RootObject but with the Newtonsoft JSON libary. I would like to use the Microsoft library. Do I really need to switch to Newtonsoft JSON? If I can use JavaScriptSerializer library, how?
The classes that correspond to the JSON you posted are:
public class RootObject
{
public Status status { get; set; }
public Payload payload { get; set; }
}
public class Status
{
public int statusCode { get; set; }
public int errorType { get; set; }
public int errorCode { get; set; }
public string errorMessage { get; set; }
}
public class Payload
{
public List<VehicleSummary> vehicleSummary { get; set; }
}
public class VehicleSummary
{
public string vin { get; set; }
public string vehicleIdentifier { get; set; }
public string modelName { get; set; }
public string modelYear { get; set; }
public string nickName { get; set; }
public int generation { get; set; }
public string extColorCode { get; set; }
public string trim { get; set; }
public Image imagePath { get; set; }
public int enrollmentStatus { get; set; }
public int fatcAvailable { get; set; }
public int telematicsUnit { get; set; }
public int fuelType { get; set; }
public string colorName { get; set; }
public int activationType { get; set; }
public string mileage { get; set; }
public string dealerCode { get; set; }
public List<MobileStore> mobileStore { get; set; }
public SupportedApp supportedApp { get; set; }
public int supportAdditionalDriver { get; set; }
public int customerType { get; set; }
public string vehicleKey { get; set; }
}
public class Image
{
public string imageName { get; set; }
public string imagePath { get; set; }
public string imageType { get; set; }
public ImageSize imageSize { get; set; }
}
public class ImageSize
{
public string length { get; set; }
public string width { get; set; }
public int uom { get; set; }
}
public class MobileStore
{
public int osType { get; set; }
public string downloadURL { get; set; }
public Image image { get; set; }
}
public class SupportedApp
{
public string appType { get; set; }
public Image appImage { get; set; }
}
I was able to deserialize the JSON just fine using JavaScriptSerializer like this:
var root = new JavaScriptSerializer().Deserialize<RootObject>(result);
where result is the JSON string you posted in your question.
Note, however, that if you have placed your classes inside another class called TestStruct then you would need to take that into account and deserialize to TestStruct.RootObject instead, e.g.:
var root = new JavaScriptSerializer().Deserialize<TestStruct.RootObject>(result);
I was also able to deserialize the JSON using Json.Net in the same way with the JsonConvert class:
var root = JsonConvert.DeserializeObject<RootObject>(result);
Once you have the deserialized object, you can extract some interesting information from it like this:
foreach (var vs in root.payload.vehicleSummary)
{
Console.WriteLine(string.Format("{0} - {1} {2} {3}, {4} mi",
vs.vin, vs.colorName, vs.modelYear, vs.modelName, vs.mileage));
}
Here is a working demo using Json.Net: https://dotnetfiddle.net/Zh35be
I have a need to serialize this from Objects, or possibly a object of objects in c#. I have tried multiple different ways to get the same output and have failed. Here is the JSON
{
"resourceType": "Observation",
"code": {
"coding": [
{
"system": "http://",
"code": "3637",
"display": "Gene"
}
],
"text": "Dip"
},
"subject": {
"reference": "Pat",
"display": ""
},
"valueString": "*1/*1",
"component": [
{
"code": {
"coding": [
{
"system": "http://",
"code": "",
"display": "Gene"
}
]
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://",
"code": "",
"display": "CYP"
}
]
}
}
]
}
i created the following objects from this. I tried to make a object containing them and then use Newtonsoft to serialize it but I can not get it right
here are the objects
public class Rootobject
{
public string resourceType { get; set; }
public Code code { get; set; }
public Subject subject { get; set; }
public string valueString { get; set; }
public Component[] component { get; set; }
}
public class Code
{
public Coding[] coding { get; set; }
public string text { get; set; }
}
public class Coding
{
public string system { get; set; }
public string code { get; set; }
public string display { get; set; }
}
public class Subject
{
public string reference { get; set; }
public string display { get; set; }
}
public class Component
{
public Code1 code { get; set; }
public Valuecodeableconcept valueCodeableConcept { get; set; }
}
public class Code1
{
public Coding1[] coding { get; set; }
}
public class Coding1
{
public string system { get; set; }
public string code { get; set; }
public string display { get; set; }
}
public class Valuecodeableconcept
{
public Coding2[] coding { get; set; }
}
public class Coding2
{
public string system { get; set; }
public string code { get; set; }
public string display { get; set; }
}
As Sir Rufo pointed out(for completeness of answer)
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var obj = CreateRootObject();
var str = JsonConvert.SerializeObject( obj, Formatting.Indented );
Console.WriteLine(str);
}
private static Rootobject CreateRootObject()
{
var obj = new Rootobject() {
resourceType = "Observation",
code = new Code() {
coding = new Coding[] {
new Coding() {
system = "http://",
code = "3637",
display = "Gene",
},
},
text = "Dip",
},
subject = new Subject() {
reference = "Pat",
display = "",
},
valueString = "*1/*1",
component = new Component[] {
new Component() {
code = new Code2(){
coding = new Coding[] {
new Coding(){
system = "http://",
code = "3637",
display = "Gene",
},
},
},
valueCodeableConcept = new Valuecodeableconcept(){
coding = new Coding[] {
new Coding(){
system = "http://",
code = "",
display = "CYP",
},
},
},
},
},
};
return obj;
}
}
public class Rootobject
{
public string resourceType { get; set; }
public Code code { get; set; }
public Subject subject { get; set; }
public string valueString { get; set; }
public Component[] component { get; set; }
}
public class Code
{
public Coding[] coding { get; set; }
public string text { get; set; }
}
public class Coding
{
public string system { get; set; }
public string code { get; set; }
public string display { get; set; }
}
public class Subject
{
public string reference { get; set; }
public string display { get; set; }
}
public class Component
{
public Code2 code { get; set; }
public Valuecodeableconcept valueCodeableConcept { get; set; }
}
public class Code2
{
public Coding[] coding { get; set; }
}
public class Valuecodeableconcept
{
public Coding[] coding { get; set; }
}
I`m trying to build web api for complex object. For this aim I built the custom binder which deserialize this object from JSON.
My Customer Binder looks like:
var paramType = p_BindingContext.ModelType;
dynamic updatedParam = Activator.CreateInstance(paramType);
JsonReader reader = new JTokenReader(JObject.Parse
(p_ActionContext.Request.Content.ReadAsStringAsync().Result));
JObject jObject = JObject.Load(reader);
JsonSerializer serializer = new JsonSerializer();
serializer.Populate(jObject.CreateReader(), updatedParam);//Here the exception thorws
p_BindingContext.Model = updatedParam;
The object to serialize is very comlex:
public class ModelRegisterUserRequest{
public ModelUser User { get; set; }
public CampaignItem CampaignWithChosenProposal { get; set; }
public string ValidationToken { get; set; }
public string IVRToken { get; set; }
public string DealerID { get; set; }
public string SalePersonID { get; set; }
}
public class CampaignItem
{
public List<BannerItem> Banners { get; set; }
public string Code { get; set; }
public string CustomerInstruction { get; set; }
public string InfoLink { get; set; }
public string LobbySubTitle { get; set; }
public string LobbyTitle { get; set; }
public string MoreText { get; set; }
public uint NumOfColumns { get; set; }
public uint NumOfRows { get; set; }
public string OriginString { get; set; }
public int OriginInt { get; set; }
public List<ProposalItem> Proposals { get; set; }
public string RegulationsInfoLink { get; set; }
public string ServiceType { get; set; }
public string SubTitle { get; set; }
public string SWDefault { get; set; }
public string Title { get; set; }
}
public partial class ProposalItem
{
public List<string> EquipmentsCode { get; set; }
public string FeatureCode { get; set; }
public string InvalidReason { get; set; }
public bool IsExistsMoreInfo { get; set; }
public bool IsValid { get; set; }
public string LeadCode { get; set; }
public int ParamCombinationCode { get; set; }
public string ProductCode { get; set; }
public string ProductCombinationCode { get; set; }
public string ProposalCode { get; set; }
public List<ColumnItem> Columns { get; set; }
public List<MoreInfoItem> MoreInfoList { get; set; }
public List<string> PricePlans { get; set; }
public string ProductName { get; set; }
}
The Json is created with JSON.stringify command from Javascript code and look like :
{
"ValidationToken": "1cc6cca8-44d5-4042-af37-de6a0d198d17",
"AppID": "TST",
"campaignWithChosenProposal": {
"Banners": [
{
"LocationCodeString": "ManagerTab",
"LocationCodeInt": 256,
"MediaUrl": "BANNER 10"
}
],
"Code": "CAMP221",
"CustomerInstruction": "-1",
"InfoLink": "http://test.aspx",
"LobbySubTitle": "",
"LobbyTitle": "",
"MoreText": "",
"NumOfColumns": 0,
"NumOfRows": 0,
"OriginString": "INT",
"OriginInt": 4,
"Proposals": [
[
{
"EquipmentsCode": [
"5455"
],
"FeatureCode": "BE5455",
"InvalidReason": "",
"IsExistsMoreInfo": true,
"IsValid": true,
"LeadCode": "3792956510",
"ParamCombinationCode": 0,
"ProductCode": "OANTIVRP2",
"ProductCombinationCode": "0",
"ProposalCode": "291600010201C8F83661D5B82FD5F3603967588B7A72",
"Columns": [
{
"Content": ""
},
{
"Content": ""
},
{
"Content": ""
},
{
"Content": ""
},
{
"Content": ""
},
{
"Content": ""
}
],
"MoreInfoList": [
{
"Content": "3",
"MoreInfoTypesString": "LicenseFrom",
"MoreInfoTypesInt": 16
},
{
"Content": "3",
"MoreInfoTypesString": "LicenseTo",
"MoreInfoTypesInt": 32
},
{
"Content": "4.3",
"MoreInfoTypesString": "PricePeriod1",
"MoreInfoTypesInt": 64
}
],
"PricePlans": [
"O2"
],
"ProductName": ""
}
]
],
"RegulationsInfoLink": "http://www.test.aspx",
"ServiceType": "TST",
"SubTitle": "",
"SWDefault": "1",
"Title": ""
},
"User": {
"CurrentLicenseNumber": 0,
"CustomerID": "21670106",
"FirstName": "",
"LastName": "",
"RequestedLicenseNumber": "3",
"SubscriberPhoneNumber": "035448428",
"IdentityNumber": "058470",
"Email": "alexanrbe#gmail.com",
"RegistrationStatus": "NOTREGISTERED"
},
"SalePersonID": "3178364",
}
The Exception is thrown on serilization row and looks like:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type WebAPI.Models.Entities.Campaigns.CampaignObjects.ProposalItem' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
I spent nights for resolve this exception but did not find any solutions
Also the solutions on this site are excisted but not supports such complex problem.
https://stackoverflow.com/questions/11126242/using-jsonconvert-deserializeobject-to-deserialize-json-to-a-c-sharp-poco-class
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
Somebody met such JSON unexpected behaiviour and could help?
Thanks
According to your JSON data, the objects that you need to map to have to look like this (unless you have your own JsonDeserializer of course):
public class Banner
{
public string LocationCodeString { get; set; }
public int LocationCodeInt { get; set; }
public string MediaUrl { get; set; }
}
public class CampaignWithChosenProposal
{
public List<Banner> Banners { get; set; }
public string Code { get; set; }
public string CustomerInstruction { get; set; }
public string InfoLink { get; set; }
public string LobbySubTitle { get; set; }
public string LobbyTitle { get; set; }
public string MoreText { get; set; }
public int NumOfColumns { get; set; }
public int NumOfRows { get; set; }
public string OriginString { get; set; }
public int OriginInt { get; set; }
public List<List<>> Proposals { get; set; }
public string RegulationsInfoLink { get; set; }
public string ServiceType { get; set; }
public string SubTitle { get; set; }
public string SWDefault { get; set; }
public string Title { get; set; }
}
public class User
{
public int CurrentLicenseNumber { get; set; }
public string CustomerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string RequestedLicenseNumber { get; set; }
public string SubscriberPhoneNumber { get; set; }
public string IdentityNumber { get; set; }
public string Email { get; set; }
public string RegistrationStatus { get; set; }
}
public class RootObject
{
public string ValidationToken { get; set; }
public string AppID { get; set; }
public CampaignWithChosenProposal campaignWithChosenProposal { get; set; }
public User User { get; set; }
public string SalePersonID { get; set; }
}
Here is a really cool tool (json2csharp) to help you out.