NewtonSoft JsonConverter and the slash character - c#

I am trying to create a dictionary from a Json array returned from a Web API which contains a file path value. I have extracted a sample here
JsonConvert.DeserializeObject<Dictionary<string, string>>("[{'Path':'\6\6553_20140729_134527059.mp3'}]")
Various combinations produce the following error. Only 1 approach works and I would love to know why. If someone can help.. much appreciated
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<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.
Path '', line 1, position 1
The following throw the above error
//Escape with double slash
JsonConvert.DeserializeObject<Dictionary<string, string>>("[{'Path':'\\6\\6553_20140729_134527059.mp3'}]")
//Escape with quadruple slash
JsonConvert.DeserializeObject<Dictionary<string, string>>("[{'Path':'\\\\6\\\\6553_20140729_134527059.mp3'}]")
//Multiple Json Objects in array
JsonConvert.DeserializeObject<Dictionary<string, string>>("[{'Path':'\\6\\6553_20140729_134527059.mp3'},{'Path':'\\6\\6553_20140729_134527059.mp3'}]")
//Double slash, single Json object
JsonConvert.DeserializeObject<Dictionary<string, string>>("{'Path':'\\6\\6553_20140729_134527059.mp3'}")
This is the only thing that works
//Quadruple slash, single object
JsonConvert.DeserializeObject<Dictionary<string, string>>("{'Path':'\\\\6\\\\6553_20140729_134527059.mp3'}")
Like I said earlier, any help would be much appreciated
ALL THE TESTS DONE IN VISUAL STUDIO QUICK WATCH

When JSON starts with "[", it means that it represents List/Array, so the deserializer expect a List of some kind as parameter,
List<Dictionary<string, string>> in your case.

Related

Get motion data for minut sensor using C#

I have an issue with getting only the motion sensor data using the minut Api, I try follow this documentation: https://api.minut.com/latest/docs#tag/Devices/paths/~1devices~1{device_id}~1motion_events/get
and I got an error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'SensorReading+API_CustomEntity' 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.
Path '[0]', line 2, position 3.'
The error happens in this line of codes (the motion events), the rest of the codes there is no error:
List<SensorReading.API_CustomEntity> SoundLevelReadings = JsonConvert.DeserializeObject<List<SensorReading.API_CustomEntity>>(DeserializeAPIObj(SOUNDLEVEL));
List<SensorReading.API_CustomEntity> TemperatureReadings = JsonConvert.DeserializeObject<List<SensorReading.API_CustomEntity>>(DeserializeAPIObj(TEMPERATURE));
List<SensorReading.API_CustomEntity> HumidityReadings = JsonConvert.DeserializeObject<List<SensorReading.API_CustomEntity>>(DeserializeAPIObj(HUMIDITY));
List<SensorReading.API_CustomEntity> MotionEventsReadings = JsonConvert.DeserializeObject<List<SensorReading.API_CustomEntity>>(DeserializeAPIObj(MOTIONEVENTS));

Error: Cannot deserialize the current JSON object

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Movie]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'Movies', line 2, position 13.
You are trying to deserialize JSON into an array type but your JSON is not of type array.

Deserialize JSON Array with JSON.NET JArray

I'm trying to deserialize my JSON Array using Newtonsoft JSON.NET nugget:
Here's the code:
private List<TemplateTypesObj> getTemplateTypes(JArray array)
{
List<TemplateTypesObj> templateTypes = Newtonsoft.Json.JsonConvert.DeserializeObject<List<TemplateTypesObj>>(array);
return templateTypes;
}
The only issue is that DeserializeObject takes String, not an JArray object. I can do array.toString() but I'm not sure if that is a proper way to do that.
That's because a JArray doesn't really need deserializing. It's not a string/binary representation of an object (which is something you'd deserialize). It's already an object which represents your JSON. You can use it like an object - iterate through it, extract individual items from it.
Check out the docs at http://www.newtonsoft.com/json/help/html/t_newtonsoft_json_linq_jarray.htm - there are methods in there which I'm sure could be used to achieve the conversion you want.

Twitter : Cannot deserialize a JSON array into an object because the type requires a JSON object

I am using TweetSharp to retrieve tweets which in turn uses JSON.NET by Newtonsoft. And this is the app code, very simple.
ListTweetsOnUserTimelineOptions listTweetsOnUserTimelineOptions =
new ListTweetsOnUserTimelineOptions();
listTweetsOnUserTimelineOptions.ScreenName = "MarilynDenisCTV";
listTweetsOnUserTimelineOptions.IncludeRts = false;
var tweets = twitterService.ListTweetsOnUserTimeline(listTweetsOnUserTimelineOptions).Take(50);
There is one tweet that is giving me trouble. And the Exception I am getting is in this line of code in TweetSharp source.
public virtual object DeserializeJson(string content, Type type)
{
using (var stringReader = new StringReader(content))
{
using (var jsonTextReader = new JsonTextReader(stringReader))
{
return _serializer.Deserialize(jsonTextReader, type);
}
}
}
This is the exception I am getting
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'TweetSharp.TwitterStatus' 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.
Path '',
I downloaded the latest source from TweetSharp, but that doesn't seem to help, any ideas why? One more thing, the one problem tweet starts with [{"created_at": "Sun Nov 03 21:44:51 +0000 2013", as supposed to {"created_at": "Sun Nov 03 21:44:51 +0000 2013", it has the extra square bracket.
Ok, through some investigation, i was able to dig into the source code of TweetSharp while debugging my application.
The reason, that the JSON Deserializer is throwing exception in my case, is because some users twitted emoji cons in their tweets, like smiley faces, sad faces. Those emoji cons are NOT encoded, before passing to JSON, hence that is what is breaking the JSON Deserailizer.
I didn't have the time to make any changes to the Tweetsharp code, since at work we are in the process of switching to another library. Content team just removed those tweets that had badly encoded emoji cons. That was a quick and dirty fix

JSON.NET exception when deserializing an array of GUIDs

I'm using JSON.NET to deserialize AJAX HTTP requests sent in from the browser, and am running into problems with web service calls that use a Guid[] as a parameter. This worked fine when I used the built in .NET serializer.
First off, the raw bytes in the stream look like this:
System.Text.Encoding.UTF8.GetString(rawBody);
"{\"recipeIds\":[\"d9ede305-d244-483b-a435-abcf350efdb2\"]}"
I then call:
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
parameters[0] = serializer.Deserialize(sr, operation.Messages[0].Body.Parts[0].Type);
.Type is System.Guid[]
I then get the exception:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Guid[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'recipeIds', line 1, position 13.
Web service methods that take in a single Guid (not an array) work, so I know JSON.NET is able to convert a string into a GUID, but it seems to blow up when you have an array of strings that you want to deserialize to an array of GUIDs.
Is this a JSON.NET bug, and is there a way to fix this? I suppose I could write my own custom Guid collection type, but I'd rather not.
You need a wrapper class
string json = "{\"recipeIds\":[\"d9ede305-d244-483b-a435-abcf350efdb2\"]}";
var obj = JsonConvert.DeserializeObject<Wrapper>(json);
public class Wrapper
{
public Guid[] recipeIds;
}
--EDIT--
Using Linq
var obj = (JObject)JsonConvert.DeserializeObject(json);
var guids = obj["recipeIds"].Children()
.Cast<JValue>()
.Select(x => Guid.Parse(x.ToString()))
.ToList();

Categories