Serialize and deserialize datetime with newtonsoft - c#

I have a class which contains the ocject DateTime.
public class Refuel
{
public DateTime DateTime { get; set; }
public string Litre { get; set; }
}
When deserializing my text file I get an error.
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[OD_TankApp.Models.Refueling]' 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 'DateTime', line 1, position 12.
I tried already with Json settings but it didnt helped.
JsonSerializerSettings settings = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat};
this is the json string:
"{\"DateTime\":\"2019-02-28T16:21:06.36845+01:00\",\"Litre\":\"23\"}}"

You are trying to deserialize a json string which represents a single object into a list/array of objects which will not work. Either deserialize it into a single object like this:
var obj = JsonConvert.DeserializeObject<Refuel>(json);
Or change your json string to contain a list of objects:
"[{\"DateTime\":\"2019-02-28T16:21:06.36845+01:00\",\"Litre\":\"23\"}]"
Now you can deserialize it like that:
var objArray = JsonConvert.DeserializeObject<Refuel[]>(json);

If you want to deserialize an array, you'll need to secify that ([])
JsonConvert.DeserializeObject<Refuel[]>(json);

Related

Json deserialization - System.Collections.Generic.List error [duplicate]

This question already has answers here:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1
(6 answers)
WriteLine with a class
(9 answers)
Closed last year.
I got http result in JSON like that
{
"success":true,
"message":[
],
"conversationList":[
"dd184c5a-7eb7-4e98-b588-975853c51b18",
"a3c25d14-d0d5-4e79-928b-1123fe1ba587",
"8c5e2869-43f8-4555-9afd-3b1e679d5ed0",
"843dcbd4-33fc-487f-9971-7fd80ff378c4",
"62dcee64-aeb6-448d-9422-c6b94a22aa02",
"409a8da6-bf32-4dee-923c-213a9971283c"
]
}
I make classes like that:
public class Root
{
public bool success { get; set; }
public List<object> message { get; set; }
public List<string> conversationList { get; set; }
}
and deserialization like this:
var deserializedJson = JsonConvert.DeserializeObject<List<Root>>(result);
Then I got this error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ConsoleApp9.Root]' 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 'success', line 1, position 11.'
I want to use foreach on this and get all conversationList. How can I resolve this error?
you don' t have a list in your root. Use this
var deserializedJson = JsonConvert.DeserializeObject<Root>(result);

Deserialize Json into C# Collection

I want to deserialize json into collection of C# objects but getting following error:
{"Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1 because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo 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.\r\nPath 'organizations', line 1, position 17."}
Code:
var jSon = "{\"Houses\":[{\"id\":\"123\",\"doorNumber\":22},
{\"id\":\"456\",\"deniNumber\":99}
]}";
var temp = JsonConvert.DeserializeObject<List<House>>(jSon);
}
public class House
{
public int Id { get; set; }
public int DoorNumber { get; set; }
}
The JSON you've shown is an Object with a Property called Houses that contains your array. Note how the outer Json is surrounded by { } and not [ ] which is why you're seeing that error. You'll need to select only the value of that property if you want to deserialize to a list of House. You can do that using JObject and then selecting the Houses property specifically.
var jobj = JObject.Parse(jSon);
var houses = JsonConvert.DeserializeObject<List<House>>(jobj["Houses"].ToString());
Alternatively you could do:
var houses = JObject.Parse(jSon)["Houses"].ToObject<List<House>>();
If you want to be able to map it in one step without using JObject you'd have to have another class that wraps your House list and maps directly to the JSON you've shown.
public class HouseList
{
public List<House> Houses {get; set;}
}
Given this object you'd be able to do
var houses = JsonConvert.DeserializeObject<HouseList>(jSon).Houses;

Convert an FeedResponse<Class> into List<Class> in DocumentDB

I'm trying to convert a FeedResponse into List but failing to serialize the string as it throws an error
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Lutran.Api.Models.Infinity]' 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 'token', line 1, position 9.
I have used the logic for pagination using the this link and getting the data when returning the entire output object but when im trying to convert it fails.Tried using an ienumerable object but it shows type conversion error.Used a dynamic object but cannot extract ResponseContinuation value from it.
Using Newton Soft to convert the json(deserialize the string)
var query = client.CreateDocumentQuery<Document>(collection, options).AsDocumentQuery();
if (query.HasMoreResults)
{
var result = await query.ExecuteNextAsync<LeadDataView>();
objLeadDataView.ResponseContinuation = result.ResponseContinuation;
objLeadDataView.InfinityDataView = JsonConvert.DeserializeObject<List<Infinity>>(result.ToString());
response = objLeadDataView;
}
I Figured it out
public class LeadDataView
{
public string ResponseContinuation { get; set; }
public FeedResponse<Infinity> InfinityDataView { get; set; }
}
if (query.HasMoreResults)
{
var result = await query.ExecuteNextAsync<Infinity>();
objLeadDataView.ResponseContinuation = result.ResponseContinuation;
objLeadDataView.InfinityDataView = result;
response = objLeadDataView;
}
So the above code sent the continuation token on top and infinity class data below.enter image description here

Mass Transit unable to deserialize collections with exactly one element

I've got a Mass Transit message interface like this:
public interface IPerson
{
ICollection<PersonalName> Names { get; }
}
public class PersonalName
{
public string FamilyName { get; set; }
public string GivenName { get; set; }
public string SecondName { get; set; }
public string Use { get; set; }
}
And this works for serializing and deserializing the message using the JsonMessageSerializer. I can also serialize the message using the XmlMessageSerializer, and the result looks a bit like this:
<person>
<names>
<familyName>Simpson</familyName>
<givenName>Homer</givenName>
<secondName>Jay</secondName>
<use>Official</use>
</names>
<names>
<givenName>Homie</givenName>
<use>Nickname</use>
</names>
</person>
And I can deserialize just it if the collection is empty or if it has more than one element. However, if the collection contains exactly one element, when I go to deserialize it, I get this error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.ICollection`1[MyNs.PersonalName]' 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 'person.names.familyName'.
I can fix this by using an array or List<T>, but I'd really like to avoid doing that. Is there a way to get Mass Transit's XmlMessageSerializer to deserialize ICollection<T> types? Since Mass Transit uses Json.NET for serialization under the hood (even for XML), I'm hoping there's some way of annotating the type so that it can accept an ICollection<T>.
Instead of trying to deserialize:
{"FamilyName":"Smith","GivenName":"John"}
you have to pass in an array to deserialize:
[{"FamilyName":"Smith","GivenName":"John"}]

Trying to deserialize JSON using JSON.NET and DataContractJsonSerializer fails

plz help, I'm stuck.
I have a WCF service which returns something like this:
{
"GetDataRESTResult":
[
{"Key1":100.0000,"Key2":1,"Key3":"Min"},
{"Key1":100.0000,"Key2":2,"Key3":"Max"}
]
}
and I would like to deserialize it, but whatever I use (JSON.NET or DataContractJsonSerializer) I'm getting errors.
When using DataContractJsonSerializer I'm using theis code:
byte[] data = Encoding.UTF8.GetBytes(e.Result);
MemoryStream memStream = new MemoryStream(data);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<DataDC>));
List<DataDC> pricinglist = (List<DataDC>)serializer.ReadObject(memStream);
where DataDC is the data contract which I've got from the service reference of the WCF REST service I'm getting the JSON data from, and the error I'm getting is InvalidCastException...
Trying to use JSON.NET I get another exception, but still nothing I can figure out, can anyone help please?
EDIT
Here's a JSON.NET stacktrace:
Cannot deserialize the current JSON object (e.g. {"name":"value"})
into type
'System.Collections.Generic.List`1[MyApp.MyServiceReference.DataDC]'
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 'GetDataRESTResult', line 1,
position 23.
{"GetDataRESTResult":[{"Key1":100.0000,"Key2":1,"Key3":"Min"},{"Key1":100.0000,"Key2":2,"Key3":"Max"}]}
You data is a JSON object (where it has one key 'GetDataRESTResult' with a JSON array as the value). Because of that, the type you should deserialize into should be an object, not a collection.
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DataDC));
DataDC pricinglist = (DataDC)serializer.ReadObject(memStream);
It will work if your type DataDC look something like this:
public class DataDC
{
public List<Keys> GetDataRESTResult { get; set; }
}
public class Keys
{
public double Key1 { get; set; }
public int Key2 { get; set; }
public string Key3 { get; set; }
}
Below code works
string json = #" {""GetDataRESTResult"":[{""Key1"":100.0000,""Key2"":1,""Key3"":""Min""},{""Key1"":100.0000,""Key2"":2,""Key3"":""Max""}]}";
dynamic dynObj = JsonConvert.DeserializeObject(json);
foreach (var item in dynObj.GetDataRESTResult)
{
Console.WriteLine("{0} {1} {2}", item.Key1, item.Key3, item.Key3);
}
You can also use Linq
var jObj = (JObject)JsonConvert.DeserializeObject(json);
var result = jObj["GetDataRESTResult"]
.Select(item => new
{
Key1 = (double)item["Key1"],
Key2 = (int)item["Key2"],
Key3 = (string)item["Key3"],
})
.ToList();

Categories