Im getting this error while trying to deserialize JSON string to object :
"System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> Newtonsoft.Json.JsonSerializationException: Error converting value "{"Admin":false,"Id":1,"Password":"heslo","Nick":"jozifek"}" to type 'Entities.dbo.User'. Path 'Frontman', line 1, position 105. ---> System.ArgumentException: Could not cast or convert from System.String to Entities.dbo.User.
at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
--- End of inner exception stack trace ---
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type)
at BussinessLogic.helpers.Serializer.Deserialize[T](String obj) in C:\Users\Ondra\documents\visual studio 2010\Projects\webServiceTestApp\BussinessLogic\helpers\Serializer.cs:line 14
at webServiceTestApp.Service1.GetSongs(String band) in C:\Users\Ondra\documents\visual studio 2010\Projects\webServiceTestApp\webServiceTestApp\Service1.asmx.cs:line 142
--- End of inner exception stack trace ---"
User.cs looks like this:
namespace Entities.dbo
{
[TableName("tbl_user")]
public class User : AbstractEntity
{
[MapField("nick")]
public string Nick { get; set; }
[MapField("password")]
public string Password { get; set; }
[MapField("admin")]
public bool Admin { get; set; }
}
}
and Band.cs looks like this:
namespace Entities.dbo
{
[TableName("tbl_band")]
public class Band : AbstractEntity
{
[MapField("name")]
public string Name { get; set; }
[MapField("frontman")]
public int FrontmanId { get; set; }
[Association(CanBeNull = false, ThisKey = "FrontmanId", OtherKey = "Id")]
public User Frontman { get; set; }
AbstractEntity:
namespace Entities.helpers
{
public abstract class AbstractEntity
{
[PrimaryKey, Identity, MapField("id")]
public int Id { get; set; }
public string Serialize()
{
return JsonConvert.SerializeObject(this);
}
}
}
and this error pops out when im sending string to deserialize as Band containing User object in Frontman property..
any idea where I went wrong?
thanks :)
its hard to say, i have use jonson once few years ago, but
in jonson you have property "Password" but in object you have MapField("password") - in lower case
Is in AbstractEntity class "Id" property?
Related
My JSON string is like this:
{
"number": "1",
"optionsList": [
"{\"answer\":\"42\", \"options\":\"washington\"}",
"{\"answer\":\"65\", \"options\":\"new england\"}"
]
}
I understand the optionsList JSON is malformed and not correct JSON but I cannot change this and would like to handle this in my code. Such that it can be deserialized correctly into a c# class.
I did:
Root.cs
public class Root {
public Root() {
Number = new Number();
OptionsList = new List<OptionsList>();
}
[JsonProperty(PropertyName = "number")]
public string Number { get; internal set; }
[JsonProperty(PropertyName = "optionsList")]
public List<OptionsList> OptionsList { get; internal set; }
}
OptionsList.cs
public class OptionsList {
[JsonProperty(PropertyName = "answer")]
public string Answer { get; internal set; }
[JsonProperty(PropertyName = "options")]
public string Options { get; internal set; }
}
Deserializing like this: deserializedResponse = JsonConvert.DeserializeObject<T>(response); //response is the JSON Object
By simply doing this, I am getting an exception.
Exception trace:
---> Newtonsoft.Json.JsonSerializationException: Error converting value "{"answer":"42","options":"washington"}" to type 'Types.OptionsList'. Path 'OptionsList[0]', line 1, position 1947.
---> System.ArgumentException: Could not cast or convert from System.String to Types.OptionsList.
at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
--- End of inner exception stack trace ---
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonConverter[] converters)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonConverter[] converters)
How can I deserialize optionsList into a c# class correctly?
Maybe if I can deserialize each string of optionsList individually before this, it would work but I don't know where to do this. Or can I add something in the constructor of OptionsList or the Root class itself to do this?
you have an array of json strings inside of a json string. So you have to deserialize the nesteded json strings at first
var jObj = JObject.Parse(json);
jObj["optionsList"] = new JArray(jObj["optionsList"]
.Select(x => JObject.Parse((string)x)));
Root data = jObj.ToObject<Root>();
I have successfully set up, configured, and run the MassTransit (v8.0.3) JobConsumers sample and am now trying to customize to my project. After modifying, I'm getting deserialization issues when submitting my job:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MyNamespace.Foo' 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 'foos[0]'.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
at MassTransit.Serialization.JsonConverters.InterfaceProxyConverter.CachedConverter`1.MassTransit.Serialization.JsonConverters.BaseJsonConverter.IConverter.Deserialize(JsonReader reader, Type objectType, JsonSerializer serializer) in /_/src/MassTransit.Newtonsoft/Serialization/JsonConverters/InterfaceProxyConverter.cs:line 31
at MassTransit.Serialization.JsonConverters.BaseJsonConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) in /_/src/MassTransit.Newtonsoft/Serialization/JsonConverters/BaseJsonConverter.cs:line 15
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
at MassTransit.Serialization.NewtonsoftObjectDeserializer.DeserializeObject[T](Object value, T defaultValue) in /_/src/MassTransit.Newtonsoft/Serialization/NewtonsoftObjectDeserializer.cs:line 34
at MassTransit.Serialization.BaseSerializerContext.DeserializeObject[T](Object value, T defaultValue) in /_/src/MassTransit/Serialization/EnvelopeSerializerContext.cs:line 52
at MassTransit.JobServiceEventExtensions.GetJob[TJob](ConsumeContext`1 context) in /_/src/MassTransit/JobServiceEventExtensions.cs:line 24
at MassTransit.JobService.FinalizeJobConsumer`1.Consume(ConsumeContext`1 context) in /_/src/MassTransit/JobService/JobService/FinalizeJobConsumer.cs:line 45
at MassTransit.Middleware.MethodConsumerMessageFilter`2.MassTransit.IFilter<MassTransit.ConsumerConsumeContext<TConsumer,TMessage>>.Send(ConsumerConsumeContext`2 context, IPipe`1 next) in /_/src/MassTransit/Middleware/MethodConsumerMessageFilter.cs:line 27
at MassTransit.Middleware.LastPipe`1.Send(TContext context) in /_/src/MassTransit.Abstractions/Middleware/Middleware/LastPipe.cs:line 30
at MassTransit.Consumer.DelegateConsumerFactory`1.Send[TMessage](ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Consumers/Consumer/DelegateConsumerFactory.cs:line 29
at MassTransit.Consumer.DelegateConsumerFactory`1.Send[TMessage](ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Consumers/Consumer/DelegateConsumerFactory.cs:line 39
at MassTransit.Middleware.ConsumerMessageFilter`2.MassTransit.IFilter<MassTransit.ConsumeContext<TMessage>>.Send(ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Middleware/ConsumerMessageFilter.cs:line 46
I am using MassTransit.Newtonsoft for JSON support because I use it in my project and due to issues encountered when upgrading to MassTransit v8. It is configured here:
x.UsingRabbitMq((context, cfg) =>
{
cfg.UseNewtonsoftJsonSerializer();
cfg.UseNewtonsoftJsonDeserializer();
...
}
Here is my message definition (that replaces the sample's ConvertVideo), stripped down to the smallest failing case:
public interface ProcessFoos
{
List<Foo> Foos { get; }
}
where Foo is defined as:
public class Foo
{
public string FooID { get; set; }
}
I'm initiating a new job from a different consumer by calling:
var foos = new List<Foo>
{
new Foo { FooID = "foo" }
};
Response<JobSubmissionAccepted> response = await _processFoosClient.GetResponse<JobSubmissionAccepted>(new
{
Foos = foos
});
My job consumer looks like this:
public class ProcessFoosJobConsumer : IJobConsumer<ProcessFoos>
{
public async Task Run(JobContext<ProcessFoos> context)
{
// Never gets here due to the deserialization issue
var processFoos = context.Job;
...
}
}
Based on the MassTransit docs and everything I've found while researching, it seems like this should be supported and I'm probably just missing something simple.
When using Entity Framework with the built-in JobServiceDbContext, the Job property in the JobSaga table is serialized to JSON using System.Text.Json – which is not compatible with the serialization of Newtonsoft when it comes to nested object (the job message type is converted to a Dictionary<string,object>).
I don't know of a current fix at this point, since there isn't a way to dynamically specify the serializer based upon the incoming message types for the DbContext.
Or you could create your own mappings, and your own DbContext, with the Newtonsoft serializer methods instead of the ones used in v8.
Your best bet when using job consumers and the job service sagas with Cosmos or EF is to use System.Text.Json.
This question already has answers here:
Casting interfaces for deserialization in JSON.NET
(17 answers)
Deserialize collection of interface-instances?
(9 answers)
Closed 3 years ago.
I'm trying to deserialize a json back to the object.
I have a List of interface in the object, which on deserializing is failing.
Pasting the code below.
Model
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public List<IAddress> Addresses { get; set; }
}
public abstract class IAddress
{
public string HomeTown { get; set; }
}
public class Address : IAddress
{
public string Location { get; set; }
public string Street { get; set; }
public string Zip { get; set; }
}
The code to serialize and deserialize are as follows:
var personObj = new Person
{
Name = "John Doe",
Age = 30,
Addresses = new List<IAddress>
{
new Address
{
Location = "location1",
Street = "Vzk",
Zip = "686670"
}
}
};
var json = JsonConvert.SerializeObject(personObj);
System.Console.WriteLine(json);
/*
{
"Name": "John Doe",
"Age": 30,
"Addresses": [{
"Location": "location1",
"Street": "Vzk",
"Zip": "686670",
"HomeTown": null
}]
}
*/
var p2 = JsonConvert.DeserializeObject<Person>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
System.Console.WriteLine((p2.Addresses[0] as Address).Zip);
The error that I'm getting is:
Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Could not create an instance of type Human.IAddress. Type is an interface or abstract class and cannot be instantiated. Path 'Addresses[0].Location', line 1, position 53.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at Parser.Program.Main(String[] args) in d:\expmts\csharp\Person\Parser\Program.cs:line 82
Is there any way to make NewtonSoft understand that, for type IAddress, Address is the type to be initiated.
Thanks in advance.
I am parsing a large data file with JSON elements in C#. Deserialization fails for some strings with the error below.
Exception = Invalid cast from 'DateTime' to 'Int64'.
Message = Error converting value 3/28/2172 12:00:00 AM to type 'System.Int64'. Path 'ProductDetail.productId', line 1, position 4003."
The error doesn't occur for all strings, but seems to suggest the value is being interpreted as a DateTime value; although, it's defined as a long within the associated class.
Can I force the value to be interpreted as a long?
ProductDetail.productId is defined as a member of the following type:
public class ProductDetail
{
public string accreditedInvestorInd { get; set; }
public string accrueAcreteInd { get; set; }
public DateTime issueDate { get; set; }
// ... truncated for simplicity
public long productId { get; set; }
// ... truncated for simplicity
public string wkndHolPayInd { get; set; }
public string zeroCouponInd { get; set; }
}
I tried unsuccessfully to use a converter attribute with the hope of forcing a different interpretation. (Not sure if I'm using it correctly)...
[JsonConverter(typeof(string))]
public long productId { get; set; }
Also, I am using a custom DateTime format.
Here is a subset of the large data file I am trying to deserialize that corresponds to ProductDetail:
{"accrueAcreteInd":"Y","callableInd":"Y","calledInd":"N","cpnCurrency":"USD","cpnPmtFreqCode":"S","cpnRate":"2.8","curAmtOutstanding":"7825000.0","currencyCode":"USD","cusip":"3130H0AX1","datedDate":"20160303","dayCountMonthCode":"30","dayCountYearCode":"360","daysToSettle":"1","dtcEligibleInd":"Y","eomPmtInd":"N","exchange":"TRACE","fatcaCode":"1","firstCpnPmtDate":"20160901","hqlaCode":"2A","identifier":"3130H0AX1","identifierType":"cusip","inDefaultInd":"N","infoSourceCode":"R21RB","intAccrued":".91777778","intTypeCode":"FIX","is144aInd":"N","issueCountry":"US","issueDate":"20160303","issuePrice":"100.0","issuerIndustryCode":"11","issuerName":"FARMER MAC","issuerTicker":"FAMCA","lastCpnPmtDate":"20250901","lastUpdateTime":"20160830","lastUpdateTimeExt":"00:06:58","longDesc":"FAMCA 2.8 03/01/2026","maturityDate":"20260301","minDenom":"1000.0","minParAmount":"1000.0","mktSectorDes":"Govt","mtnInd":"Y","nextCallDate":"20170301","nextCallPrice":"100.0","nextCpnPmtDate":"20170301","origIssueAmt":"7825000.0","prevCpnPmtDate":"20160901","primaryIssInd":"Y","privatePlacementInd":"N","productId":"21720328","productTypeCode":"FRMNT","putableInd":"N","pxCleanInd":"Y","redempVal":"100.0","regSInd":"N","restrictedInd":"N","secHoldInd":"N","securityType":"FAMCCL","series":"NOTZ","shortDesc":"FAMCA 2.8 03/26","sinkableInd":"N","traceEligibleInd":"N","truePutInd":"N","wkndHolPayInd":"N","zeroCouponInd":"N"}
And here is how I am trying to deserialize the subset, where Line is the JSON string above:
var dateFormatSettings = new JsonSerializerSettings { DateFormatString = "yyyyMMdd" };
var detail = JsonConvert.DeserializeObject<ProductDetail>(Line, dateFormatSettings);
And here is the full exception for the simplified JSON:
Newtonsoft.Json.JsonSerializationException: Error converting value 3/28/2172 12:00:00 AM to type 'System.Int64'. Path 'productId', line 1, position 1117. ---> System.InvalidCastException: Invalid cast from 'DateTime' to 'Int64'.
at System.DateTime.System.IConvertible.ToInt64(IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
--- End of inner exception stack trace ---
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
The problem is related to the specific DateFormatString you are using:
var dateFormatSettings = new JsonSerializerSettings { DateFormatString = "yyyyMMdd" };
JSON has no literal syntax for dates and so, at a low level, Json.NET does some pattern matching to recognize strings that are dates, using the DateFormatString setting. Unfortunately your DateFormatString setting of yyyyMMdd matches both of the following JSON properties:
"issueDate":"20160303", // Should deserialize to a DateTime
"productId":"21720328", // Should deserialize to a long
And so, while the first is correctly recognized as a date, the second is also, eventually causing the "Invalid cast from 'DateTime' to 'Int64'." exception at a higher code level. It's a bit of an edge case since it's unexpected for a JSON string value corresponding to a long member to be parsable as both a long and a DateTime, but this is arguably a bug in Json.NET.
You have a couple workarounds:
Disable automatic date recognition by setting JsonSerializerSettings.DateParseHandling = DateParseHandling.None:
var dateFormatSettings = new JsonSerializerSettings
{
DateParseHandling = DateParseHandling.None,
DateFormatString = "yyyyMMdd"
};
Members explicitly typed as DateTime will still be correctly deserialized despite disabling low-level automatic recognition.
Use an IsoDateTimeConverter { DateTimeFormat = "yyyyMMdd" } rather than setting JsonSerializerSettings.DateFormatString.
var dateFormatSettings = new JsonSerializerSettings
{
Converters = { new IsoDateTimeConverter { DateTimeFormat = "yyyyMMdd" } }
};
Members explicitly typed as DateTime will be deserialized using your desired format string while leaving the pattern used for low-level automatic recognition unchanged.
Sample fiddle reproducing the problem and demonstrating the two workarounds.
I'm having some trouble serializing/deserializing in RavenDB. I have no problems storing the data, but have an issue when querying the documents.
I have a fairly complex Account class that was generated from Entity Framework v4.3 POCO generator:
[Serializable]
public class Account
{
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime CreatedDate { get; set; }
public List<Product> ProductsOwned { get; set; }
public bool IsActive { get; set; }
public Nullable<DateTime> DOB { get; set; }
public Address HomeAddress { get; set; }
// shortened for brevity
}
When I query my objects and return them as a List, I get a .NET Reflection Error "object does not match target type".
var results = (from account in mySession.Query<Account>()
where account.IsActive == true
select account).ToList<Account>(); // this is where error occurs
I thought this could be because I have other nested classes and nullables that are being serialized as well when I save it, but I found that I could create a "wrappper" class called AccountWrapper like this:
public class AccountWrapper
{
public Guid Id { get; set; }
public string SerializedText { get; set; }
}
Here I would manually use JSON.NET (yes, the same .dll's that shipped with RavenDB Buid 960) to populate the SerializedText field and then store it to RavenDB. This process would work! I would get the AccountWrapper object out of RavenDB and then manually deserialize the contents of SerializedText. This leads me to believe there may be an issue with the default (de)serialization process.
So my question is, is there a way I can manually override the Serialize/Deserialize functionality on RavenDB when I store/load my documents? If so, can someone show me a clean example of how to do so? I could then possibly make it use the standard JsonConverter.Serialize() as part of JSON.NET
Obviously using the AccountWrapper is a bad idea because I can't index on the "real" data that I need to query on.
(Full Stack Trace of Exception Below)
System.Reflection.TargetException: Object does not match target type. at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Newtonsoft.Json.Serialization.JsonContract.InvokeOnDeserialized(Object o, StreamingContext context) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonContract.cs:line 172
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IWrappedCollection wrappedList, JsonReader reader, String reference, JsonArrayContract contract) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 774
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.<>c__DisplayClass1.<CreateAndPopulateList>b__0(IList l, Boolean isTemporaryListReference) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 744
at Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList(Type listType, Action`2 populateList) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Utilities\CollectionUtils.cs:line 233
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateList(JsonReader reader, String reference, JsonArrayContract contract) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 732
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String reference) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 495
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 238
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueProperty(JsonReader reader, JsonProperty property, JsonConverter propertyConverter, Object target, Boolean gottenCurrentValue, Object currentValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 213
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonReader reader, Object target) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 617
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, String id) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 1203
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, String id) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 956
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 433
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 236
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract, JsonConverter converter) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 221
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 117
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\JsonSerializer.cs:line 421
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\JsonSerializer.cs:line 413
at Raven.Client.Connection.JsonExtensions.Deserialize(RavenJObject self, Type type, DocumentConvention convention) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Connection\JsonExtensions.cs:line 30
at Raven.Client.Document.InMemoryDocumentSessionOperations.ConvertToEntity[T](String id, RavenJObject documentFound, RavenJObject metadata) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:line 416
at Raven.Client.Document.InMemoryDocumentSessionOperations.TrackEntity[T](String key, RavenJObject document, RavenJObject metadata) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:line 340
at Raven.Client.Document.SessionOperations.QueryOperation.Deserialize[T](RavenJObject result) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\SessionOperations\QueryOperation.cs:line 130
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Raven.Client.Document.SessionOperations.QueryOperation.Complete[T]() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\SessionOperations\QueryOperation.cs:line 114
at Raven.Client.Document.AbstractDocumentQuery`2.GetEnumerator() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\AbstractDocumentQuery.cs:line 616
at Raven.Client.Linq.RavenQueryInspector`1.GetEnumerator() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryInspector.cs:line 98
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
This should work, can you provide additional details, and a failing test case would be great.
At any rate, you can customize this using:
documentStore.Conventions.CustomizeSerializer