无法将类型为“Newtonsoft.Json.Linq.JObject”的对象强制转换为“System.Runtime.Serialization.ISafeSerializationData”

我试图反序列化一个web api调用得到以下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.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.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: 

我的代码:

 public SensoriaApiResult PostSensoriaApiResult(object body) { HttpClient client = SetupClient(); HttpResponseMessage response; response = client.PostAsJsonAsync(url, body).Result; SensoriaApiResult result = response.Content.ReadAsAsync<SensoriaApiResult>().Result; return result; } 

Json回来了:

 {"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.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.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.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.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":[{"k__BackingField":false}]},"CLR_SafeSerializationManager_RealType":"System.Data.Entity.Infrastructure.DbUpdateException, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"},"ModelState":null} 

Generic APIResult类定义:

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

}

由于这个问题差不多有两年了,我非常怀疑我能对原版海报有什么帮助,但是对于任何搜索这个错误的人来说,这是因为许多实体数据框架exception没有实现序列化构造函数,而是依赖于SerializeObjectState事件(就像System.Net.Http.HttpRequestException一样,这恰好是过去几个小时一直让适应的小错误)。 正如此错误报告中所述,JSON.NET无法正确处理这种情况。

关于HttpRequestException的序列化/反序列化,这个可怕的黑客为我解决了这个问题:

 string myJson = JsonConvert.SerializeObject(myObject).Replace("\"SafeSerializationManager\":", "\"_SafeSerializationManager\":"); 

当我尝试使用HttpRequestException类型的内部exception对一个exception(我序列化)进行反序列化时,我遇到了这个问题。 无法解除此exception,因为它没有GetObjectData实现。

我的解决方案是在序列化之前删除HttpRequestException实例。

如果您观察到返回的json,表示序列化exception,那么有趣的部分就在这里:

…“InnerException”:{“Errors”:[{“source”:“。Net SqlClient Data Provider”,“number”:547,“state”:0,“errorClass”:16,“server”:“。 “,”message“:”INSERT语句与FOREIGN KEY约束冲突\“FK_UserBase.ClosetItems_Catalog.Products \”。冲突发生在数据库\“Sensoria.Knowledge.Database \”,表\“dbo.Catalog.Products \ “,列’ProductId’。”,“procedure”:“”,“lineNumber”:1,“win32ErrorCode”:0},{“source”:“。Net SqlClient Data Provider”,“number”:3621,“state “:0,”errorClass“:0,”server“:”。“,”message“:”语句已被终止。“,”procedure“:”“,”lineNumber“:1,”win32ErrorCode“:0} ],“ClientConnectionId”:“7b976c29-59ff-491c-a3aa-01750e17cb36”,“ClassName”:“System.Data.SqlClient.SqlException”,“Message”: “INSERT语句与FOREIGN KEY约束冲突”FK_UserBase。 ClosetItems_Catalog.Products \“。冲突发生在数据库\”Sensoria.Knowledge.Database \“,table \”dbo.Catalog.Products \“,列’ProductId’ 。\ r \ n语句已终止。”,“Dat a::{“HelpLink.ProdName”:“Microsoft SQL …

即本声明:

INSERT语句与FOREIGN KEY约束冲突 \”FK_UserBase.ClosetItems_Catalog.Products \“。冲突发生在数据库\” Sensoria.Knowledge.Database \“,table \” dbo.Catalog.Products \“,列‘ProductId’ **

所以我建议你观察一下你正在接受和传递的一个参数body的价值: PostSensoriaApiResult(object body) 。 可能有一些ProductId不存在(通常为0 ,即任何int属性的默认值)