2014-05-20 59 views
4

我收到以下異常,試圖反序列化一個web api調用 - 消息是模糊的,所以我可以「不懂是怎麼回事 - 這個轉換工作在其他情況下,不知道什麼是錯在這裏:無法轉換'Newtonsoft.Json.Linq.JObject'類型的對象來鍵入'System.Runtime.Serialization.ISafeSerializationData'

例外:

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: 

我的代碼:

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; 
    } 

JSON的returne d:

{"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} 

的通用APIResult類定義:

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; 

    ... 

}

回答

5

既然這個問題已經快2歲了,我很懷疑我可以向任何幫助原始海報,但任何人googling這個錯誤,這是由於許多實體數據框架異常沒有實現序列化構造函數,而是依賴於SerializeObjectState事件(System.Net.Http。HttpRequestException,恰好是在過去的幾個小時內一直給予的小bug)。 JSON.NET沒有正確處理這種情況,如this錯誤報告中所述。

+0

節省了多少時間。非常感謝。 – MaYaN

1

如果您發現返回的JSON,代表系列化例外,最有趣的部分是在這裏:

...「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「,」消息「:」INSERT語句與FOREIGN KEY約束\「FK_UserBase.ClosetItems_Catalog.Products \」衝突。數據庫\「Sensoria.Knowledge.Database \」,表\「dbo.Catalog.Products \」,列'ProductId'。\ r \ n該語句已終止。「,」Data「:{」HelpLink .ProdName 「:」 微軟SQL ...

即本聲明:

「的INSERT語句衝突與外鍵約束 \」 FK_UserBase.ClosetItems_Catalog.Products \」衝突發生在數據庫「Sensoria.Knowledge.Database」中,表「dbo.Catalog.Products」,列'ProductId' **

所以我建議去觀察一個PARAM body,你所recieving和傳球的價值:PostSensoriaApiResult(object body)。可能有一些ProductId不存在(經常,即任何int屬性的默認值)

+0

謝謝你的回覆! 我知道這是錯誤 - 但我想將這些信息轉換爲我的類型:SensoriaApiResult 具有Exception屬性,以便客戶端可以檢查它。 不幸的是,反序列化/投射失敗,客戶端留下了一個無法理解的例外。 - – MaurGi

+0

我想說,問題是:您應該先閱讀迴應。將它反序列化爲某個對象,捕獲該進程的任何異常。實施決策樹 - 在repsonse包含錯誤而不是期望結果的情況下。接下來,有了這個信息,你應該手工(在代碼中)用你處理過的信息填寫你的'SensoriaApiResult'。這些將被正確地序列化。我會說......分成一步。一次不做全部 –

1

我試圖對HttpRequestException類型的內部異常進行去序列化(我將其序列化)的異常時出現了此問題。 由於它沒有執行GetObjectData,因此無法取消該異常。

我的解決方案是在序列化之前刪除HttpRequestException實例。

相關問題