Please clarify some confusion for me: I have a JSON string that I am trying to stick into an object, but I only want to take in the top level, and treat everything underneath as a blob or string. Something like this.
Here is my model:
public class InputJson
{
[JsonProperty(PropertyName = "signals")]
public string signals{ get; set; }
[JsonProperty(PropertyName = "options")]
public string options { get; set; }
[JsonProperty(PropertyName = "fields")]
public string fields{ get; set; }
[JsonProperty(PropertyName = "lapse")]
public string lapse{ get; set; }
}
and I am trying to deserialize the JSON string (see below) to it like so:
InputJson a = JsonConvert.DeserializeObject<InputJson>(body);
I would expect that a.signals
would return a string, with everything underneath "signals" and before "options", but it fails because its trying to go forward and serialize everything underneath it. I get a JsonReaderException
:
Error reading string. Unexpected token: StartArray. Path 'signals', line 1, position 12.
I tried playing around with JsonSerializerSettings
(like setting maxDepth to 1) but nothing helped. Anyone?
my JSON string:
{
"signals":
[
{
"name":"1",
"att1":"44",
"att2":"0",
"att3":"18",
"size":10,
"points":[-79,-29,-9,-23,27,-110,-39,-22,-32,-2]
},
{
"name":"2",
"att1":"46",
"att2":"0",
"att3":"12",
"size":10,
"points":[36,37,37,35,38,41,41,45,39,41]
}
],
"options":"opt1 opt2",
"fields":"myfields",
"lapse":"somelapse"
}
As you correctly surmised, you are getting this error because your field is string and the deserializer has found an array. It cannot assign an array to a string.
You can solve this problem by using a custom JsonConverter
for the fields that you want treated as "blobs", by which I assume you mean you just want the raw JSON string.
Here is the code you would need for the converter:
class BlobJsonConverter: JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(string));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
return token.ToString(Formatting.None);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Then, in your model, decorate those string properties that you want treated as "blobs" with a [JsonConverter]
attribute like this:
public class InputJson
{
[JsonProperty(PropertyName = "signals")]
[JsonConverter(typeof(BlobJsonConverter))]
public string signals { get; set; }
[JsonProperty(PropertyName = "options")]
public string options { get; set; }
[JsonProperty(PropertyName = "fields")]
public string fields { get; set; }
[JsonProperty(PropertyName = "lapse")]
public string lapse { get; set; }
}
Now when you deserialize, signals
will contain the raw JSON underneath "signals" instead of giving an error.
Demo:
class Program
{
static void Main(string[] args)
{
string json = @"
{
""signals"":
[
{
""name"":""1"",
""att1"":""44"",
""att2"":""0"",
""att3"":""18"",
""size"":10,
""points"":[-79,-29,-9,-23,27,-110,-39,-22,-32,-2]
},
{
""name"":""2"",
""att1"":""46"",
""att2"":""0"",
""att3"":""12"",
""size"":10,
""points"":[36,37,37,35,38,41,41,45,39,41]
}
],
""options"":""opt1 opt2"",
""fields"":""myfields"",
""lapse"":""somelapse""
}";
InputJson a = JsonConvert.DeserializeObject<InputJson>(json);
Console.WriteLine("signals: " + a.signals);
Console.WriteLine("options: " + a.options);
Console.WriteLine("fields: " + a.fields);
Console.WriteLine("lapse: " + a.lapse);
}
}
Output:
signals: [{"name":"1","att1":"44","att2":"0","att3":"18","size":10,"points":[-79,-29,-9,-23,27,-110,-39,-22,-32,-2]},{"name":"2","att1":"46","att2":"0","att3":"12","size":10,"points":36,37,37,35,38,41,41,45,39,41]}]
options: opt1 opt2
fields: myfields
lapse: somelapse
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With