Skip empty arrays in JSON deserialize - c#

I'm trying to read a JSON document from a REST web service with Newsoft.JsonNET
The document contains some empty arrays:
{
"values": [null]
}
This is how a filled array looks like:
{
"values": ["first", "second", "third"]
}
My model class looks like this:
[DataContract]
public class MyModel
{
[DataMember]
public IEnumerable<MyEnum> Values{ get; }
public MyModel(IEnumerable<MyEnum> values)
{
this.Values = values;
}
}
public MyEnum
{
First,
Second,
Third
}
The null in those empty array causes an ArgumentNullException.
How can I solve this?

Related

Json.NET : Detect an absence of a property on Json which appears to be a member of my object

I'm trying to deserialize some Json objects using Json.NET. I'd like to be able to detect if I have a member in my class missing from the Json properties for that object. For instance, I have a class which looks like this :
public class MyClass
{
public int n;
public bool b;
public string s;
}
And a Json which looks like this
{"n":1,"b":true}
so it's missing the "s" property. When I try to deserialize that, members which are not in the Json will have default value. So "s" will be equal to null. Fair enough, but is it possible to detect that when I'm deserializing ?
In substance, I want to do pretty much the opposite of this Stackoverflow post
But in my case, the MissingMemberHandling setting seems to do nothing, sadly.
Json.Net provides a way to achieve that.
You can set an attribute on the property in your Model class. and if
that property is not available in JSON it'll throw an exception.
Here is the Example
Model
public class Videogame
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
[JsonProperty(Required = Required.AllowNull)]
public DateTime? ReleaseDate { get; set; }
}
Test Code
string json = #"{
'Name': 'Starcraft III'
}";
Videogame starcraft = JsonConvert.DeserializeObject<Videogame>(json);
You can read more about this here
This is what i can think of at the moment.
public void CheckData()
{
if(n == null)
{
Console.Write("n is null");
}
if (b == null)
{
Console.Write("b is null");
}
if (s == null)
{
Console.Write("s is null");
}
}
Run a method like that after json maps to the object to see if there were any still null.
Or you can try something like this
var fields = typeof(MyClass).GetFields();
foreach (var field in fields)
{
if(!json.ContainsKey(field.Name))
{
Console.Write($"{field.Name} is missing");
}
}

Creating a custom JSON tokenizer

I am trying to parse JSON into a token object. Right now Im using JSON.Net to generate a static class, and parsing it using Json2csharp, but I would like to make each array element its own Token object and I'm not quite sure how to do that. Do I need to implement my own JSON parser? I can modify the JSON object as needed.
My JSON Deserializer: JSONopMap jo = JsonConvert.DeserializeObject<JSONopMap>(myjson2);
public class JSONopMap
{
List<List<string>>addr {get;set;}
}
JSON
{
'addr':[['~address'],['removeall','.'],['append',' ','~age']]
}
My end goal is to create a MyToken class like this:
public class MyToken
{
public enum tokenType {get;set;}
public List<string> parts {get;set;}
}
public class TokenParent{
public string ResultName{get;set;}
public List<MyToken> mytokens{get;set;}
}
public enum tokenType{Map,Append,Removeall,Lower}
So I would have three MyToken objects like this:
new MyToken{
tokenType=Map,
parts=new List<string>(){"~address"}
}
new MyToken{
tokenType=Removeall,
parts=new List<string>(){"."}
}
new MyToken{
tokenType=Append,
parts=new List<string>(){" ","~age"}
}
and a parent which contained them all:
new TokenParent{
ResultName="addr",
mytokens = (the tokens created above)
}

Unable to Serialize JSON to Dictionary

I have an issue with JSON serialization into a class with a dictionary property.
The whole process is a bit more complex, as an input i have a YAML file that i convert into a json using YamlDotNet and NewtonSoft like so
This is an example of the Yaml and the JSON output
some_element: '1'
should_be_dic_element:
- a: '1'
- b: '2'
{
"some_element": "1",
"should_be_dic_element": [
{
"a": "1"
},
{
"b": "2"
}
]
}
And the class
public class SomeClass
{
[JsonProperty(PropertyName = "some_element")]
public string SomeProperty { get; set; }
[JsonProperty(PropertyName = "should_be_dic_element")]
public Dictionary<string, string> Dictionary { get; set; }
}
I know the issue with Array dictionary so this are all the things I've tried.
Using Dictionary i get the following
error Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' 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 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
Using a new class from Dictionary like so
[JsonArray]
class X : Dictionary<string, string> { }
error Value cannot be null.
Parameter name: key
Using KeyValuePair<string, string>[] / List<KeyValuePair<string, string>> the outcome is the amount of elements but with null values.
Any suggestions please ?
I think your JSON which you are attempting to de-serialize is not conforming to your class definition. Try changing the way you are generating the JSON.
For a dictionary-type structure, I would expect to see curly braces { instead of [ to begin the structure, e.g.:
{
"some_element": "1",
"should_be_dic_element": {
{
"a": "1"
},
{
"b": "2"
}
}
}
If you want to deserialize the existing JSON unchanged, try using your class definition to specify a list of dictionaries as such:
public class SomeClass
{
[JsonProperty(PropertyName = "some_element")]
public string SomeProperty { get; set; }
[JsonProperty(PropertyName = "should_be_dic_element")]
public List<Dictionary<string, string>> Dictionary { get; set; }
}

Serialize to JSON Array of object<string, string>

I need my JSON output to be like the following (array of object}:
{
"values":[{"1","one"},{"2","two"},{"3","three"},{"4","four"}]
}
However, when I serialize the following C# class:
public class MyObject
{
public List<string>[] values {get;set}
}
It results in the following (array of array):
{
"values":[["1","one"],["2","two"],["3","three"],["4","four"]]
}
I've tried many variations on this object. Like the following:
public class MyObject
{
public KeyValuePair[] values {get;set}
}
Which gives me (array of KeyValuePair):
{
"values":[{"Key":"1","Value":"one"},{"Key":"2","Value":"two"},{"Key":"3","Value":"three"},{"Key":"4","Value":"four"}]
}
Is there a C# object property which would serialize to an array of json objects which do not have the object property names included?:
{
"values":[{"1","one"},{"2","two"},{"3","three"},{"4","four"}]
}
I may be answering my own question here, but here is what I found. The following will return an array of objects without property names. However, it is a hack and uses the Dictionary Key as the json property name:
public class MyObject
{
public Dictionary<string, string>[] values { get; set; }
}
Which yields the following:
{
"values":[{"1":"one"},{"2":"two"},{"3":"three"},{"4":"four"}]
}

JSON.net problem with JsonConvert.DeserializeObject

I have the following code and json:
public class Labels
{
public Labels()
{}
public Label[] Label {get;set;}
}
public class Label
{
public Label()
{ }
public string Name { get; set; }
public int TorrentsInLabel { get; set; }
}
//...
Labels o = JsonConvert.DeserializeObject<Labels>(json);
//...
{"label":
[
["seq1",1]
,["seq2",2]
]}
I would like this array ["seq1","1"] to deserialize into Label object. What am I missing? Some attributes?
When I run I get exception: Expected a JsonArrayContract for type 'test_JSONNET.Label', got 'Newtonsoft.Json.Serialization.JsonObjectContract'.
tnx
gg
How can JsonConvert know that "seq1" corresponds to name and "1" corresponds to the TorrentsInLabel? Please have a look at JsonObjectAttribute, JsonPropertyAttribute, JsonArrayAttribute
By default a class serializes to a JSON object where the properties on the class become properties on the JSON object.
{
Name: "seq",
TorrentsInLabel: 1
}
You are trying to serialize it to an array which isn't how the Json.NET serializer works by default.
To get what you want you should create a JsonConverter and read and write the JSON for Label manually to be what you want it to be (an array).

Categories

Resources