I am unable to deserialize the Tags property of my JSON:
{
"posts": [
{
"ID": 7096,
"title": "Backwards Pipe Operator",
"URL": "https://bizmonger.wordpress.com/2017/10/26/backwards-pipe-operator/",
"tags": {
"F#": {
"ID": 6012,
"name": "F#"
}
}
}
]
}
From the JSON above I provided the following types:
type Post = {
title: string
URL: string
Tags: JToken seq // Used to refer to the string instead of the property type
}
type Response = { posts: Post list }
I'm running into an exception when attempting to deserialize the Tags property of a Post value:
let settings = JsonSerializerSettings()
settings.MissingMemberHandling <- MissingMemberHandling.Ignore
let result = JsonConvert.DeserializeObject<Response>(json, settings)
Newtonsoft.Json.JsonSerializationException occurred
HResult=0x80131500 Message=Cannot deserialize the current JSON
object (e.g. {"name":"value"}) into type
'System.Collections.Generic.IEnumerable`1[Newtonsoft.Json.Linq.JToken]'
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 'posts[0].tags.F#', line 1,
position 1582. Source=
StackTrace: at
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader
reader, Type objectType, JsonContract contract, JsonProperty member,
JsonContainerContract containerContract, JsonProperty containerMember,
Object existingValue) ...
Appendix:
Here's the JSON URL
try let url = String.Format(ArticlesUrl, user.AccessId)
let response = client.GetAsync(url) |> Async.AwaitTask
|> Async.RunSynchronously
if response.IsSuccessStatusCode
then let json = response.Content.ReadAsStringAsync() |> Async.AwaitTask
|> Async.RunSynchronously
let settings = JsonSerializerSettings()
settings.MissingMemberHandling <- MissingMemberHandling.Ignore
let result = JsonConvert.DeserializeObject<Response>(json, settings);
The library tells you very explicitly what's wrong: Cannot deserialize ... JSON object ... into type 'JToken seq' because the type requires a JSON array to deserialize correctly.
Seq is a sequence (i.e. a list, an array, an enumeration) of stuff. It corresponds to JSON array, not to JSON object.
To deserialize a JSON object without knowing property names in advance, use IDictionary:
type Post = {
title: string
URL: string
Tags: IDictionary<string, JToken>
}
Further, if you do know the shape of each individual tag (ID + name), then you can do even better:
type Tag = { ID: string; name: string }
type Post = {
title: string
URL: string
Tags: IDictionary<string, Tag>
}
Related
i cant create a post using the version 2.0.1 on asp.net CORE
This is the Code:
var client = new WordPressClient( "http://sitioweb.com/wp-json/" );
client.Auth.UseBasicAuth( "username", "app_password" );
var post = new Post() {
Title = new Title( "ITCmx" ),
Content = new Content( "Content PostCreate" )
};
var createdPost = await client.Posts.CreateAsync( post );
And get this error
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
'WordPressPCL.Models.Post' 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. Path '',
line 1, position 1.
I try on Postman and works fine
Could you please help me
Thank you
You need to convert your data to json before sending
using Newtonsoft.Json;
var json = JsonConvert.SerializeObject(post);
var createdPost = await client.Posts.CreateAsync( json);
I would like to read a JSON string via the Newtonsoft Json library. It works fine for any basic datatype, but it does not work for a List<double> or any List for that matter.
The test application looks like the following:
static void main()
{
string jsonString = #"
{
'name': 'set1',
'Xvv': {
'parameter': 'hByT',
'values': '[1,2,3]'
}
}";
JObject Json = JObject.Parse(jsonString);
var name = Json["name"].ToString();
var data = Json["Xvv"]["values"].Value<List<double> >(); // Raises error
}
The last line throws the following exception:
System.InvalidCastException: Invalid cast from 'System.String' to 'System.Collections.Generic.List
Is there a way to access the data directly as a List<double>?
In the example JSON you've provided, values is a string. A proper JSON array would be
'values': [1,2,3]
Anyway, after changing the string to the array, .Value<List<double>>() would throw an exception, that a JArray cannot be cast to a JToken - unfortunately I do not really know, why it does not work.
However, JToken.ToObject<T> does the trick, it
Creates an instance of the specified .NET type from the JToken
(see the documentation for ToObject)
With the line
var data = Json["Xvv"]["values"].ToObject<List<double>>();
you can cast the array correctly.
If an IEnumerable would be fine for you, too, you could also use
var data = Json["Xvv"]["values"].Values<double>();
I need to deserialize json file with unknown keys and unknown ammount of keys
{"key1":"val01", "key2":"val02", "key3":"val03", ..., "keyn":"val0n"}
{"key1":"val11", "key2":"val12", "key3":"val13", ..., "keyn":"val1n"}
{"key1":"val21", "key2":"val22", "key3":"val23", ..., "keyn":"val2n"}
I don't know the keys and even don't know n.
I've tried to parse it as list of dictionaries:
res = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(jsontext);
but I've received an exception:
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List1[System.Collections.Generic.Dictionary2[System.String,System.String]]' 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 '/APL/HVAC/TREG/EACT', line 1, position 23..
How to get rid of this exception?
Your json is not valid. You can validate your json strings with tools like JSON Formatter
Lists should have [ in the beginning and ] in the end. You also need to put commas between elements.
A valid version of your string would be like this:
[
{
"key1": "val01",
"key2": "val02",
"key3": "val03",
"keyn": "val0n"
},
{
"key1": "val11",
"key2": "val12",
"key3": "val13",
"keyn": "val1n"
},
{
"key1": "val21",
"key2": "val22",
"key3": "val23",
"keyn": "val2n"
}
]
JSON Editor Online lets you both check and edit.
Try this:
using Newtonsoft.Json.Linq;
string json = "[{\"key1\":\"val01\", \"key2\":\"val02\", \"key3\":\"val03\", \"keyn\":\"val0n\"}, {\"key1\":\"val11\", \"key2\":\"val12\", \"key3\":\"val13\", \"keyn\":\"val1n\"}, {\"key1\":\"val21\", \"key2\":\"val22\", \"key3\":\"val23\", \"keyn\":\"val2n\"}]";
var objects = JArray.Parse(json); // parse as array
foreach(JObject obj in objects)
{
foreach(KeyValuePair<String, JToken> pair in obj)
{
Console.WriteLine(pair.Key + " -> " + pair.Value);
}
}
your json file is maybe malformed, it should start with [ and end with ] to be readable with a Dictionary<string, string>
Exemple:
[{"key1":"val01"}, {"key2":"val02"}, {"key3":"val03"}, ..., {"keyn":"val0n"}]
I've dealt with this problem using this:
var result = new List<Dictionary<string, string>>();
var jsons = jsontext.Split('\n');
foreach (var x in jsons)
{
var res = JsonConvert.DeserializeObject<Dictionary<string, string>>(x);
result.Add(res);
}
I'm trying to get tweets at the homepage of twitter. But, JsonSerializationSettingsException is thrown:
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 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.
listBox1.Items.Clear();
var option = new ListTweetsOnHomeTimelineOptions() { Count = 25, IncludeEntities = false };
var tweets = service.ListTweetsOnHomeTimeline(option);
foreach (var i in tweets)
{
string tweet = String.Format("{0} -> {1}", i.User.ScreenName, i.Text);
listBox1.Items.Add(tweet);
}
I have a Json string from Visistat.com's API that I am trying to parse in C# with Json.Net. The Json string looks like:
[
["date", "uniques"],
["2014-04-15", "613"],
["2014-04-16", "631"],
["2014-04-17", "593"],
["2014-04-18", "466"],
["2014-04-19", "305"],
["2014-04-20", "294"],
["2014-04-21", "795"],
["2014-04-22", "666"],
["2014-04-23", "625"],
["2014-04-24", "571"],
["2014-04-25", "506"],
["2014-04-26", "342"],
["2014-04-27", "351"],
["2014-04-28", "720"],
["2014-04-29", "606"],
["2014-04-30", "588"],
["2014-05-01", "508"],
["2014-05-02", "545"],
["2014-05-03", "345"],
["2014-05-04", "379"],
["2014-05-05", "833"],
["2014-05-06", "635"],
["2014-05-07", "596"],
["2014-05-08", "530"],
["2014-05-09", "539"],
["2014-05-10", "322"],
["2014-05-11", "290"],
["2014-05-12", "734"],
["2014-05-13", "684"],
["2014-05-14", "555"],
["2014-05-15", "511"]
]
I've created an object to deserialize this into:
public class DateUnique
{
public DateTime date { get; set; }
public int uniques { get; set; }
}
I'm then trying to parse the Json string with:
List<DateUnique> dateuniques = JsonConvert.DeserializeObject<List<DateUnique>>(json);
I then get this Exception:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'VisiStatSystem.DateUnique' 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.
Path '[0]', line 1, position 2.
I don't see any samples in the Json.net documentation that shows how to deserialize a Json string that looks like what is returned by the VisiStat Api. Any help appreciated!
You are getting this error because your JSON is an array of arrays, not an array of objects, while you are trying to parse it as if it were the latter. You will need a little bit of special handling to deserialize it into a List<DateUnique>.
The following code should work:
JArray array = JArray.Parse(json);
List<DateUnique> list = new List<DateUnique>(array.Count - 1);
for (int i = 1; i < array.Count; i++)
{
list.Add(new DateUnique
{
date = DateTime.ParseExact(array[i][0].ToString(),
"yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture),
uniques = int.Parse(array[i][1].ToString())
});
}