Unable to cast object of type 'Newtonsoft.Json

2019-06-16 03:47发布

I am getting the following exception trying to deserialize a web api call - the message is obscure so I can't understand what is going on - this cast works in other cases not sure what's wrong here:

Exception:

  InnerException: System.Reflection.TargetInvocationException
   _HResult=-2146232828
   _message=Exception has been thrown by the target of an invocation.
   HResult=-2146232828
   IsTransient=false
   Message=Exception has been thrown by the target of an invocation.
   Source=mscorlib
   StackTrace:
        at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
        at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
        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.<>c__DisplayClass1.<CreateSerializationCallback>b__0(Object o, StreamingContext context)
        at Newtonsoft.Json.Serialization.JsonContract.InvokeOnDeserialized(Object o, StreamingContext context)
        at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.OnDeserialized(JsonReader reader, JsonContract contract, Object value)
        at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateISerializable(JsonReader reader, JsonISerializableContract 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.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 System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, Encoding effectiveEncoding, IFormatterLogger formatterLogger)
        at System.Net.Http.Formatting.JsonMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, Encoding effectiveEncoding, IFormatterLogger formatterLogger)
        at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
     --- End of stack trace from previous location where exception was thrown ---
        at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
        at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
        at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
        at System.Net.Http.HttpContentExtensions.<ReadAsAsyncCore>d__0`1.MoveNext()
   InnerException: System.InvalidCastException
        _HResult=-2147467262
        _message=Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'System.Runtime.Serialization.ISafeSerializationData'.
        HResult=-2147467262
        IsTransient=false
        Message=Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'System.Runtime.Serialization.ISafeSerializationData'.
        Source=mscorlib
        StackTrace:
             at System.Runtime.Serialization.SafeSerializationManager.CompleteDeserialization(Object deserializedObject)
             at System.Exception.OnDeserialized(StreamingContext context)
        InnerException: 

My code:

public SensoriaApiResult<T> PostSensoriaApiResult(object body)
    {
        HttpClient client = SetupClient();

        HttpResponseMessage response;
        response = client.PostAsJsonAsync(url, body).Result;

        SensoriaApiResult<T> result = response.Content.ReadAsAsync<SensoriaApiResult<T>>().Result;
        return result;
    }

The Json returned:

{"StatusCode":500,"APIResult":null,"HttpError":{"Message":"Sensoria API internal error","SensoriaApiErrorCode":983041},"Exception":{"ClassName":"System.Data.Entity.Infrastructure.DbUpdateException","Message":"An error occurred while updating the entries. See the inner exception for details.","Data":{},"InnerException":{"ClassName":"System.Data.Entity.Core.UpdateException","Message":"An error occurred while updating the entries. See the inner exception for details.","Data":{},"InnerException":{"Errors":[{"source":".Net SqlClient Data Provider","number":547,"state":0,"errorClass":16,"server":".","message":"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_UserBase.ClosetItems_Catalog.Products\". The conflict occurred in database \"Sensoria.Knowledge.Database\", table \"dbo.Catalog.Products\", column 'ProductId'.","procedure":"","lineNumber":1,"win32ErrorCode":0},{"source":".Net SqlClient Data Provider","number":3621,"state":0,"errorClass":0,"server":".","message":"The statement has been terminated.","procedure":"","lineNumber":1,"win32ErrorCode":0}],"ClientConnectionId":"7b976c29-59ff-491c-a3aa-01750e17cb36","ClassName":"System.Data.SqlClient.SqlException","Message":"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_UserBase.ClosetItems_Catalog.Products\". The conflict occurred in database \"Sensoria.Knowledge.Database\", table \"dbo.Catalog.Products\", column 'ProductId'.\r\nThe statement has been terminated.","Data":{"HelpLink.ProdName":"Microsoft SQL Server","HelpLink.ProdVer":"11.00.3128","HelpLink.EvtSrc":"MSSQLServer","HelpLink.EvtID":"547","HelpLink.BaseHelpUrl":"http://go.microsoft.com/fwlink","HelpLink.LinkId":"20476"},"InnerException":null,"HelpURL":null,"StackTraceString":"   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)\r\n   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)\r\n   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)\r\n   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()\r\n   at System.Data.SqlClient.SqlDataReader.get_MetaData()\r\n   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)\r\n   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)\r\n   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)\r\n   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)\r\n   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)\r\n   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<>c__DisplayClassb.<Reader>b__8()\r\n   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](Func`1 operation, TInterceptionContext interceptionContext, Action`1 executing, Action`1 executed)\r\n   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)\r\n   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)\r\n   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()","RemoteStackTraceString":null,"RemoteStackIndex":0,"ExceptionMethod":"8\nOnError\nSystem.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\nSystem.Data.SqlClient.SqlConnection\nVoid OnError(System.Data.SqlClient.SqlException, Boolean, System.Action`1[System.Action])","HResult":-2146232060,"Source":".Net SqlClient Data Provider","WatsonBuckets":null},"HelpURL":null,"StackTraceString":"   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()\r\n   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)\r\n   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction, Boolean throwOnClosedConnection)\r\n   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update(Boolean throwOnClosedConnection)\r\n   at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__33()\r\n   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)\r\n   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy)\r\n   at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass28.<SaveChanges>b__25()\r\n   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)\r\n   at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)\r\n   at System.Data.Entity.Internal.InternalContext.SaveChanges()","RemoteStackTraceString":null,"RemoteStackIndex":0,"ExceptionMethod":"8\nUpdate\nEntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\nSystem.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator\nInt32 Update()","HResult":-2146233087,"Source":"EntityFramework","WatsonBuckets":null},"HelpURL":null,"StackTraceString":"   at Sensoria.Models.ShoeClosetModel.CreateClosetModelForUser(Int32 userId, ShoeClosetItem newClosetItem) in c:\\Users\\maurgi\\Source\\Hg\\sensoria-main\\Source\\Web\\Sensoria.Models\\ShoeClosetModel.cs:line 225\r\n   at Sensoria.Models.ShoeClosetModel.CreateClosetItem(Int32 userID, ShoeClosetItem newClosetItem) in c:\\Users\\maurgi\\Source\\Hg\\sensoria-main\\Source\\Web\\Sensoria.Models\\ShoeClosetModel.cs:line 76\r\n   at Sensoria.Api.Controllers.ShoeClosetController.AddNewShoe(Int32 userId, ShoeClosetItem sItem) in c:\\Users\\maurgi\\Source\\Hg\\sensoria-main\\Source\\Web\\Sensoria.Api\\Controllers\\ShoeClosetController.cs:line 79","RemoteStackTraceString":null,"RemoteStackIndex":0,"ExceptionMethod":"8\nCreateClosetModelForUser\nSensoria.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\nSensoria.Models.ShoeClosetModel\nSensoria.Models.ShoeClosetModel CreateClosetModelForUser(Int32, Sensoria.Api.Core.Models.ShoeClosetItem)","HResult":-2146233087,"Source":"Sensoria.Models","WatsonBuckets":null,"SafeSerializationManager":{"m_serializedStates":[{"<InvolvesIndependentAssociations>k__BackingField":false}]},"CLR_SafeSerializationManager_RealType":"System.Data.Entity.Infrastructure.DbUpdateException, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"},"ModelState":null}

The Generic APIResult class definition:

public class SensoriaApiResult<T>
{
    /// <summary>
    /// The 
    /// </summary>
    [DataMember]
    public HttpStatusCode StatusCode;
    [DataMember]
    public T APIResult;
    [DataMember]
    public HttpError HttpError;
    [DataMember]
    public Exception Exception;
    [DataMember]
    public ModelStateDictionary ModelState;

    ...

}

4条回答
Animai°情兽
2楼-- · 2019-06-16 04:02

If you observe the returned json, representing serialized exception, the interesting part is here:

..."InnerException":{"Errors":[{"source":".Net SqlClient Data Provider","number":547,"state":0,"errorClass":16,"server":".","message":"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_UserBase.ClosetItems_Catalog.Products\". The conflict occurred in database \"Sensoria.Knowledge.Database\", table \"dbo.Catalog.Products\", column 'ProductId'.","procedure":"","lineNumber":1,"win32ErrorCode":0},{"source":".Net SqlClient Data Provider","number":3621,"state":0,"errorClass":0,"server":".","message":"The statement has been terminated.","procedure":"","lineNumber":1,"win32ErrorCode":0}],"ClientConnectionId":"7b976c29-59ff-491c-a3aa-01750e17cb36","ClassName":"System.Data.SqlClient.SqlException","Message":"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_UserBase.ClosetItems_Catalog.Products\". The conflict occurred in database \"Sensoria.Knowledge.Database\", table \"dbo.Catalog.Products\", column 'ProductId'.\r\nThe statement has been terminated.","Data":{"HelpLink.ProdName":"Microsoft SQL ...

Namely this statement:

"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_UserBase.ClosetItems_Catalog.Products\". The conflict occurred in database \"Sensoria.Knowledge.Database\", table \"dbo.Catalog.Products\", column 'ProductId'**

So I would suggest to observe the value of a param body, which you are recieving and passing: PostSensoriaApiResult(object body). There could be some ProductId which does not exist (very often 0, i.e. the default of any int property)

查看更多
男人必须洒脱
3楼-- · 2019-06-16 04:09

I had this issue when I tried to desrialize an exception (which I serialized) with inner exception of type HttpRequestException. This exception can't be deseialized since it has no implementation of GetObjectData.

My solution was removing HttpRequestException instances before serialization.

查看更多
贼婆χ
4楼-- · 2019-06-16 04:24

Regarding the serialization/deserialization of HttpRequestException, this horrible hack fixed the issue for me:

string myJson = JsonConvert.SerializeObject(myObject).Replace("\"SafeSerializationManager\":", "\"_SafeSerializationManager\":");
查看更多
来,给爷笑一个
5楼-- · 2019-06-16 04:26

Since this question is almost 2 years old, I highly doubt I can be of any help to the original poster, but for anyone googling this error, this is caused by the fact that many entity data framework exceptions do not implement a serialization constructor, and instead rely on the SerializeObjectState event (as does System.Net.Http.HttpRequestException, which happens to be the little bugger that has been giving me fits for the past few hours). JSON.NET does not properly handle this situation, as documented in this bug report.

查看更多
登录 后发表回答