Skip to content

SqlException fails to deserialize via BinaryFormatter #778

Closed
@danlyons-home

Description

Describe the bug

In one project I work on, RPC is done via RabbitMQ, serializing request/reply data with BinaryFormatter. Recently, I ran across an error when deserializing SqlExceptions raised on the back-end.

There appear to be two distinct exceptions raised:

TargetInvokcationException with an inner exception of InvalidCastException when the deserialized exception includes SqlException as its inner exception:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.InvalidCastException: Object must implement IConvertible.
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at System.Runtime.Serialization.FormatterConverter.Convert(Object value, Type type)
   at System.Runtime.Serialization.SerializationInfo.GetValue(String name, Type type)
   at System.Exception..ctor(SerializationInfo info, StreamingContext context)
   at Panther.Common.Database.DBException..ctor(SerializationInfo info, StreamingContext context) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.common.database\DBException.cs:line 136

   --- End of inner exception stack trace ---
   at Panther.Proxy.Common.SyncRequestHelper.SendRequestAsync[T](Object scope, Object payload, TimeSpan timeout, String queueName) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.common\SyncRequestHelper.cs:line 209
   at Panther.Proxy.Common.SyncRequestHelper.SendRequestAsync[T](String queueName, Object scope, Object payload, TimeSpan timeout) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.common\SyncRequestHelper.cs:line 116
   at Panther.Common.Extensions.TaskExtensions.SynchronizeResult[T](Task`1 task) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.common\Extensions\TaskExtensions.cs:line 28
   at Panther.Proxy.Common.SyncRequestHelper.SendRequest[T](String queueName, Object scope, Object payload, TimeSpan timeout) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.common\SyncRequestHelper.cs:line 75
   at Panther.Proxy.Client.BaseFailoverProxy.SendRequest[T](Keys scope, Object payload) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.client\BaseFailoverProxy.cs:line 28
   at Panther.Proxy.Client.PrivCache.PrivCacheFailoverProxy.SavePrivilegeValues(IEnumerable`1 accountPrivs, String savedBy) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.client\PrivCache\PrivCacheFailoverProxy.cs:line 352
   at Panther.Api.Controllers.PrivilegeController.SavePrivileges(IEnumerable`1 privileges) in C:\BuildAgent\work\fb44abcc89900f2b\src\web\panther.api.core\Controllers\PrivilegeController.cs:line 270
   at lambda_method(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

SerializationException when the deserialized exception is SqlException itself:

System.Runtime.Serialization.SerializationException: Unable to load type Microsoft.Data.SqlClient.SqlException required for deserialization.
   at System.Runtime.Serialization.ObjectManager.DoFixups()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(BinaryParser serParser, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, Boolean check)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
   at testdbexception.Program.Main(String[] args) in C:\danl\testdbexception\Program.cs:line 37

To reproduce

Attached is a minimal reproduction of the issue. TestDir has functions to create a test table, insert a value, and drop the test table. Program calls into TestDir with two inserts of the same value to trigger a SqlException for a primary key violation, then serializes and deserializes the exception with BinaryFormatter.

testdbexception.zip

Expected behavior

I would expect the deserialization to complete successfully, particularly given SqlException is marked as serializable, implements ISerializable, and serializes without issue.

Further technical details

Microsoft.Data.SqlClient version: latest (2.0.1)
.NET target: Core 3.1
SQL Server version: SQL Server 2016
Operating system: Windows 10 (dev machine), Server 2016 (production machine)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    🐛 Bug!Issues that are bugs in the drivers we maintain.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions