Conditional Deserialization of either a Dictionary or a List of Objects
I am sending a GET request to a Rest API that returns some JSON in two different formats (based on some external setting that I can't influence).
I can either receive:
"content": {
"fields": [
{
"name": "test1",
"value": 1
},
{
"name": "test2",
"value": "test"
},
{
"name": "test3",
"value": "test",
"links": [...]
}
]
}
or
"content": {
"test1": 1,
"test2": "test",
"test3": "test"
}
You can see that I receive either a list of objects containing name
and value
properties (along with some other properties like links
), or I receive a single object containing key-value pairs as in a Dictionary. I now want to know if there is a way to conditionally deserialize the JSON into a class with Dictionary<string, string>
and List<Field>
properties like this:
[Serializable]
public class Content
{
/// <summary>
/// The Type of the Content
/// </summary>
public string _Type { get; set; }
public Dictionary<string, string> Dictionary { get; set; }
public List<Field> Fields { get; set; }
}
and fill either the dictionary or the list of fields depending on the JSON.
c# json json.net deserialization
|
show 2 more comments
I am sending a GET request to a Rest API that returns some JSON in two different formats (based on some external setting that I can't influence).
I can either receive:
"content": {
"fields": [
{
"name": "test1",
"value": 1
},
{
"name": "test2",
"value": "test"
},
{
"name": "test3",
"value": "test",
"links": [...]
}
]
}
or
"content": {
"test1": 1,
"test2": "test",
"test3": "test"
}
You can see that I receive either a list of objects containing name
and value
properties (along with some other properties like links
), or I receive a single object containing key-value pairs as in a Dictionary. I now want to know if there is a way to conditionally deserialize the JSON into a class with Dictionary<string, string>
and List<Field>
properties like this:
[Serializable]
public class Content
{
/// <summary>
/// The Type of the Content
/// </summary>
public string _Type { get; set; }
public Dictionary<string, string> Dictionary { get; set; }
public List<Field> Fields { get; set; }
}
and fill either the dictionary or the list of fields depending on the JSON.
c# json json.net deserialization
a custom jsonconverter that can inspect the json and extract the desired format
– Nkosi
Nov 23 '18 at 13:16
Im geusing it should be a public Dictionary<string, List<Fields>> Dictionary { get; set; }
– mahlatse
Nov 23 '18 at 13:16
No it should be Dictionary<string,string> as that is what I am expecting. The Fields Class has way more members than I need here. @Nkosi could you give me an Example or link that points me in the right direction
– Brezelmann
Nov 23 '18 at 13:50
@Brezelmann you can find details in documentation newtonsoft.com/json/help/html/CustomJsonConverter.htm
– Nkosi
Nov 23 '18 at 14:03
@Nkosi I checked your Idea. I am not sure how to do it in my case because i have two quite different data structures with either a Dictionary or a List and one of those will always be null because I can either get a Dictionary of Data or a List of Data but never both.
– Brezelmann
Nov 23 '18 at 14:45
|
show 2 more comments
I am sending a GET request to a Rest API that returns some JSON in two different formats (based on some external setting that I can't influence).
I can either receive:
"content": {
"fields": [
{
"name": "test1",
"value": 1
},
{
"name": "test2",
"value": "test"
},
{
"name": "test3",
"value": "test",
"links": [...]
}
]
}
or
"content": {
"test1": 1,
"test2": "test",
"test3": "test"
}
You can see that I receive either a list of objects containing name
and value
properties (along with some other properties like links
), or I receive a single object containing key-value pairs as in a Dictionary. I now want to know if there is a way to conditionally deserialize the JSON into a class with Dictionary<string, string>
and List<Field>
properties like this:
[Serializable]
public class Content
{
/// <summary>
/// The Type of the Content
/// </summary>
public string _Type { get; set; }
public Dictionary<string, string> Dictionary { get; set; }
public List<Field> Fields { get; set; }
}
and fill either the dictionary or the list of fields depending on the JSON.
c# json json.net deserialization
I am sending a GET request to a Rest API that returns some JSON in two different formats (based on some external setting that I can't influence).
I can either receive:
"content": {
"fields": [
{
"name": "test1",
"value": 1
},
{
"name": "test2",
"value": "test"
},
{
"name": "test3",
"value": "test",
"links": [...]
}
]
}
or
"content": {
"test1": 1,
"test2": "test",
"test3": "test"
}
You can see that I receive either a list of objects containing name
and value
properties (along with some other properties like links
), or I receive a single object containing key-value pairs as in a Dictionary. I now want to know if there is a way to conditionally deserialize the JSON into a class with Dictionary<string, string>
and List<Field>
properties like this:
[Serializable]
public class Content
{
/// <summary>
/// The Type of the Content
/// </summary>
public string _Type { get; set; }
public Dictionary<string, string> Dictionary { get; set; }
public List<Field> Fields { get; set; }
}
and fill either the dictionary or the list of fields depending on the JSON.
c# json json.net deserialization
c# json json.net deserialization
edited Nov 25 '18 at 7:08
Brian Rogers
76.4k18192204
76.4k18192204
asked Nov 23 '18 at 13:12
BrezelmannBrezelmann
397
397
a custom jsonconverter that can inspect the json and extract the desired format
– Nkosi
Nov 23 '18 at 13:16
Im geusing it should be a public Dictionary<string, List<Fields>> Dictionary { get; set; }
– mahlatse
Nov 23 '18 at 13:16
No it should be Dictionary<string,string> as that is what I am expecting. The Fields Class has way more members than I need here. @Nkosi could you give me an Example or link that points me in the right direction
– Brezelmann
Nov 23 '18 at 13:50
@Brezelmann you can find details in documentation newtonsoft.com/json/help/html/CustomJsonConverter.htm
– Nkosi
Nov 23 '18 at 14:03
@Nkosi I checked your Idea. I am not sure how to do it in my case because i have two quite different data structures with either a Dictionary or a List and one of those will always be null because I can either get a Dictionary of Data or a List of Data but never both.
– Brezelmann
Nov 23 '18 at 14:45
|
show 2 more comments
a custom jsonconverter that can inspect the json and extract the desired format
– Nkosi
Nov 23 '18 at 13:16
Im geusing it should be a public Dictionary<string, List<Fields>> Dictionary { get; set; }
– mahlatse
Nov 23 '18 at 13:16
No it should be Dictionary<string,string> as that is what I am expecting. The Fields Class has way more members than I need here. @Nkosi could you give me an Example or link that points me in the right direction
– Brezelmann
Nov 23 '18 at 13:50
@Brezelmann you can find details in documentation newtonsoft.com/json/help/html/CustomJsonConverter.htm
– Nkosi
Nov 23 '18 at 14:03
@Nkosi I checked your Idea. I am not sure how to do it in my case because i have two quite different data structures with either a Dictionary or a List and one of those will always be null because I can either get a Dictionary of Data or a List of Data but never both.
– Brezelmann
Nov 23 '18 at 14:45
a custom jsonconverter that can inspect the json and extract the desired format
– Nkosi
Nov 23 '18 at 13:16
a custom jsonconverter that can inspect the json and extract the desired format
– Nkosi
Nov 23 '18 at 13:16
Im geusing it should be a public Dictionary<string, List<Fields>> Dictionary { get; set; }
– mahlatse
Nov 23 '18 at 13:16
Im geusing it should be a public Dictionary<string, List<Fields>> Dictionary { get; set; }
– mahlatse
Nov 23 '18 at 13:16
No it should be Dictionary<string,string> as that is what I am expecting. The Fields Class has way more members than I need here. @Nkosi could you give me an Example or link that points me in the right direction
– Brezelmann
Nov 23 '18 at 13:50
No it should be Dictionary<string,string> as that is what I am expecting. The Fields Class has way more members than I need here. @Nkosi could you give me an Example or link that points me in the right direction
– Brezelmann
Nov 23 '18 at 13:50
@Brezelmann you can find details in documentation newtonsoft.com/json/help/html/CustomJsonConverter.htm
– Nkosi
Nov 23 '18 at 14:03
@Brezelmann you can find details in documentation newtonsoft.com/json/help/html/CustomJsonConverter.htm
– Nkosi
Nov 23 '18 at 14:03
@Nkosi I checked your Idea. I am not sure how to do it in my case because i have two quite different data structures with either a Dictionary or a List and one of those will always be null because I can either get a Dictionary of Data or a List of Data but never both.
– Brezelmann
Nov 23 '18 at 14:45
@Nkosi I checked your Idea. I am not sure how to do it in my case because i have two quite different data structures with either a Dictionary or a List and one of those will always be null because I can either get a Dictionary of Data or a List of Data but never both.
– Brezelmann
Nov 23 '18 at 14:45
|
show 2 more comments
1 Answer
1
active
oldest
votes
You can handle this situation by creating a custom JsonConverter
for your Content
class as shown below. It works by loading the content
portion of the JSON into a JObject
and checking for the presence of the fields
property to determine how to populate the Content
instance.
public class ContentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Content);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
Content content = new Content();
if (jo["fields"] != null)
{
// if the fields property is present, we have a list of fields
content.Fields = jo["fields"].ToObject<List<Field>>(serializer);
content._Type = "Fields";
}
else
{
// fields property is not present so we have a simple dictionary
content.Dictionary = jo.Properties().ToDictionary(p => p.Name, p => (string)p.Value);
content._Type = "Dictionary";
}
return content;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
I was not sure how you wanted to handle the _Type
property, so I just set it to either "Fields" or "Dictionary" to indicate which property was populated. Feel free to change it to suit your needs.
To use the converter, just add a [JsonConverter]
attribute to your Content
class like this:
[JsonConverter(typeof(ContentConverter))]
public class Content
{
...
}
Here is a working demo: https://dotnetfiddle.net/geg5fA
Works really nice. A good Example and a real good explanation. Thank you @Brian Rogers
– Brezelmann
Nov 30 '18 at 10:32
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53447387%2fconditional-deserialization-of-either-a-dictionary-or-a-list-of-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can handle this situation by creating a custom JsonConverter
for your Content
class as shown below. It works by loading the content
portion of the JSON into a JObject
and checking for the presence of the fields
property to determine how to populate the Content
instance.
public class ContentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Content);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
Content content = new Content();
if (jo["fields"] != null)
{
// if the fields property is present, we have a list of fields
content.Fields = jo["fields"].ToObject<List<Field>>(serializer);
content._Type = "Fields";
}
else
{
// fields property is not present so we have a simple dictionary
content.Dictionary = jo.Properties().ToDictionary(p => p.Name, p => (string)p.Value);
content._Type = "Dictionary";
}
return content;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
I was not sure how you wanted to handle the _Type
property, so I just set it to either "Fields" or "Dictionary" to indicate which property was populated. Feel free to change it to suit your needs.
To use the converter, just add a [JsonConverter]
attribute to your Content
class like this:
[JsonConverter(typeof(ContentConverter))]
public class Content
{
...
}
Here is a working demo: https://dotnetfiddle.net/geg5fA
Works really nice. A good Example and a real good explanation. Thank you @Brian Rogers
– Brezelmann
Nov 30 '18 at 10:32
add a comment |
You can handle this situation by creating a custom JsonConverter
for your Content
class as shown below. It works by loading the content
portion of the JSON into a JObject
and checking for the presence of the fields
property to determine how to populate the Content
instance.
public class ContentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Content);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
Content content = new Content();
if (jo["fields"] != null)
{
// if the fields property is present, we have a list of fields
content.Fields = jo["fields"].ToObject<List<Field>>(serializer);
content._Type = "Fields";
}
else
{
// fields property is not present so we have a simple dictionary
content.Dictionary = jo.Properties().ToDictionary(p => p.Name, p => (string)p.Value);
content._Type = "Dictionary";
}
return content;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
I was not sure how you wanted to handle the _Type
property, so I just set it to either "Fields" or "Dictionary" to indicate which property was populated. Feel free to change it to suit your needs.
To use the converter, just add a [JsonConverter]
attribute to your Content
class like this:
[JsonConverter(typeof(ContentConverter))]
public class Content
{
...
}
Here is a working demo: https://dotnetfiddle.net/geg5fA
Works really nice. A good Example and a real good explanation. Thank you @Brian Rogers
– Brezelmann
Nov 30 '18 at 10:32
add a comment |
You can handle this situation by creating a custom JsonConverter
for your Content
class as shown below. It works by loading the content
portion of the JSON into a JObject
and checking for the presence of the fields
property to determine how to populate the Content
instance.
public class ContentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Content);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
Content content = new Content();
if (jo["fields"] != null)
{
// if the fields property is present, we have a list of fields
content.Fields = jo["fields"].ToObject<List<Field>>(serializer);
content._Type = "Fields";
}
else
{
// fields property is not present so we have a simple dictionary
content.Dictionary = jo.Properties().ToDictionary(p => p.Name, p => (string)p.Value);
content._Type = "Dictionary";
}
return content;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
I was not sure how you wanted to handle the _Type
property, so I just set it to either "Fields" or "Dictionary" to indicate which property was populated. Feel free to change it to suit your needs.
To use the converter, just add a [JsonConverter]
attribute to your Content
class like this:
[JsonConverter(typeof(ContentConverter))]
public class Content
{
...
}
Here is a working demo: https://dotnetfiddle.net/geg5fA
You can handle this situation by creating a custom JsonConverter
for your Content
class as shown below. It works by loading the content
portion of the JSON into a JObject
and checking for the presence of the fields
property to determine how to populate the Content
instance.
public class ContentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Content);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
Content content = new Content();
if (jo["fields"] != null)
{
// if the fields property is present, we have a list of fields
content.Fields = jo["fields"].ToObject<List<Field>>(serializer);
content._Type = "Fields";
}
else
{
// fields property is not present so we have a simple dictionary
content.Dictionary = jo.Properties().ToDictionary(p => p.Name, p => (string)p.Value);
content._Type = "Dictionary";
}
return content;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
I was not sure how you wanted to handle the _Type
property, so I just set it to either "Fields" or "Dictionary" to indicate which property was populated. Feel free to change it to suit your needs.
To use the converter, just add a [JsonConverter]
attribute to your Content
class like this:
[JsonConverter(typeof(ContentConverter))]
public class Content
{
...
}
Here is a working demo: https://dotnetfiddle.net/geg5fA
answered Nov 25 '18 at 6:48
Brian RogersBrian Rogers
76.4k18192204
76.4k18192204
Works really nice. A good Example and a real good explanation. Thank you @Brian Rogers
– Brezelmann
Nov 30 '18 at 10:32
add a comment |
Works really nice. A good Example and a real good explanation. Thank you @Brian Rogers
– Brezelmann
Nov 30 '18 at 10:32
Works really nice. A good Example and a real good explanation. Thank you @Brian Rogers
– Brezelmann
Nov 30 '18 at 10:32
Works really nice. A good Example and a real good explanation. Thank you @Brian Rogers
– Brezelmann
Nov 30 '18 at 10:32
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53447387%2fconditional-deserialization-of-either-a-dictionary-or-a-list-of-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
a custom jsonconverter that can inspect the json and extract the desired format
– Nkosi
Nov 23 '18 at 13:16
Im geusing it should be a public Dictionary<string, List<Fields>> Dictionary { get; set; }
– mahlatse
Nov 23 '18 at 13:16
No it should be Dictionary<string,string> as that is what I am expecting. The Fields Class has way more members than I need here. @Nkosi could you give me an Example or link that points me in the right direction
– Brezelmann
Nov 23 '18 at 13:50
@Brezelmann you can find details in documentation newtonsoft.com/json/help/html/CustomJsonConverter.htm
– Nkosi
Nov 23 '18 at 14:03
@Nkosi I checked your Idea. I am not sure how to do it in my case because i have two quite different data structures with either a Dictionary or a List and one of those will always be null because I can either get a Dictionary of Data or a List of Data but never both.
– Brezelmann
Nov 23 '18 at 14:45