On the backend, we have the following model:
public record RoofDesign
{
public int CountOfPanels { get; init; }
public RoofDesignImages? Images { get; init; }
public JObject? EditorData { get; init; }
}
The end users will design the roofs in a front-end application. In addition to the finished design, we wish to store information the editor can use to continue the design session at a later time, possibly at another computer. The backend will never care about the contents of this data, so it is enough for us just to save a JSON.
The RoofDesign object is contained in an array in a PlanningProject object and I am currently saving it with the following method:
public PlanningProject UpdatePlanning(PlanningProjectUpdate projectUpdate, CancellationToken cancellationToken)
{
return Plannings.FindOneAndUpdate(
filter: CreateFilterById<PlanningProject>(projectUpdate.Id),
update: CreateUpdate(projectUpdate),
options: new FindOneAndUpdateOptions<PlanningProject, PlanningProject>
{
ReturnDocument = ReturnDocument.After
},
cancellationToken: cancellationToken
);
}
This works fine if EditorData is undefined or null.
However, if I give it a value, I get both an unexpected result and an exception.
For example, if it is populated from the value:
"editorData": {
"additionalProp1": [
null
],
"additionalProp2": [
null
],
"additionalProp3": [
null
]
}
... in the MongoDb record, it is saved like:
"EditorData" : {
"additionalProp1" : {
"_t" : "JArray",
"_v" : [
{
"_t" : "JValue",
"_v" : []
}
]
},
"additionalProp2" : {
"_t" : "JArray",
"_v" : [
{
"_t" : "JValue",
"_v" : []
}
]
},
"additionalProp3" : {
"_t" : "JArray",
"_v" : [
{
"_t" : "JValue",
"_v" : []
}
]
}
}
And then I get an error like:
ystem.FormatException: An error occurred while deserializing the Roofs property of class SoPE.Estimation.PlanningProject: An error occurred while deserializing the EditorData property of class SoPE.Estimation.RoofDesign: Exception has been thrown by the target of an invocation. ---> System.FormatException: An error occurred while deserializing the EditorData property of class SoPE.Estimation.RoofDesign: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: Could not determine JSON object type for type System.Collections.Generic.List
1[Newtonsoft.Json.Linq.JToken]. at Newtonsoft.Json.Linq.JValue.GetValueType(Nullable1 current, Object value) at Newtonsoft.Json.Linq.JValue..ctor(Object value) --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at MongoDB.Bson.Serialization.Serializers.EnumerableInterfaceImplementerSerializer2.FinalizeResult(Object accumulator) at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.Serializers.SerializerBase1.MongoDB.Bson.Serialization.IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.Serializers.DiscriminatedWrapperSerializer1.<>c__DisplayClass6_0.b__0(String elementName, Int64 flag) at MongoDB.Bson.Serialization.Serializers.SerializerHelper.DeserializeMembers(BsonDeserializationContext context, Action2 memberHandler) at MongoDB.Bson.Serialization.Serializers.DiscriminatedWrapperSerializer1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer1 serializer, BsonDeserializationContext context) at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer1 serializer, BsonDeserializationContext context) at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.Serializers.SerializerBase1.MongoDB.Bson.Serialization.IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.Serializers.DiscriminatedWrapperSerializer1.<>c__DisplayClass6_0.b__0(String elementName, Int64 flag) at MongoDB.Bson.Serialization.Serializers.SerializerHelper.DeserializeMembers(BsonDeserializationContext context, Action2 memberHandler) at MongoDB.Bson.Serialization.Serializers.DiscriminatedWrapperSerializer1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer1 serializer, BsonDeserializationContext context) at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer1 serializer, BsonDeserializationContext context) at MongoDB.Bson.Serialization.Serializers.DictionarySerializerBase3.DeserializeDocumentRepresentation(BsonDeserializationContext context) at MongoDB.Bson.Serialization.Serializers.DictionarySerializerBase3.DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.Serializers.ClassSerializerBase1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.Serializers.SerializerBase1.MongoDB.Bson.Serialization.IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize(IBsonSerializer serializer, BsonDeserializationContext context) at MongoDB.Bson.Serialization.BsonClassMapSerializer1.DeserializeMemberValue(BsonDeserializationContext context, BsonMemberMap memberMap) --- End of inner exception stack trace --- at MongoDB.Bson.Serialization.BsonClassMapSerializer1.DeserializeMemberValue(BsonDeserializationContext context, BsonMemberMap memberMap) at MongoDB.Bson.Serialization.BsonClassMapSerializer1.DeserializeClass(BsonDeserializationContext context) at MongoDB.Bson.Serialization.BsonClassMapSerializer1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer1 serializer, BsonDeserializationContext context) at MongoDB.Bson.Serialization.Serializers.EnumerableSerializerBase2.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.Serializers.SerializerBase1.MongoDB.Bson.Serialization.IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize(IBsonSerializer serializer, BsonDeserializationContext context) at MongoDB.Bson.Serialization.BsonClassMapSerializer1.DeserializeMemberValue(BsonDeserializationContext context, BsonMemberMap memberMap) --- End of inner exception stack trace --- at MongoDB.Bson.Serialization.BsonClassMapSerializer1.DeserializeMemberValue(BsonDeserializationContext context, BsonMemberMap memberMap) at MongoDB.Bson.Serialization.BsonClassMapSerializer1.DeserializeClass(BsonDeserializationContext context) at MongoDB.Bson.Serialization.BsonClassMapSerializer1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer1 serializer, BsonDeserializationContext context) at MongoDB.Driver.Core.Operations.ElementDeserializer1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer1 serializer, BsonDeserializationContext context) at MongoDB.Driver.Core.Operations.FindAndModifyValueDeserializer1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer1 serializer, BsonDeserializationContext context) at MongoDB.Driver.Core.Operations.FindAndModifyOperationBase1.ProcessCommandResult(ConnectionId connectionId, RawBsonDocument rawBsonDocument) at MongoDB.Driver.Core.Operations.FindAndModifyOperationBase1.ExecuteAttempt(RetryableWriteContext context, Int32 attempt, Nullable1 transactionNumber, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.RetryableWriteOperationExecutor.Execute[TResult](IRetryableWriteOperation1 operation, RetryableWriteContext context, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.RetryableWriteOperationExecutor.Execute[TResult](IRetryableWriteOperation1 operation, IWriteBinding binding, Boolean retryRequested, CancellationToken cancellationToken) at MongoDB.Driver.Core.Operations.FindAndModifyOperationBase1.Execute(IWriteBinding binding, CancellationToken cancellationToken) at MongoDB.Driver.OperationExecutor.ExecuteWriteOperation[TResult](IWriteBinding binding, IWriteOperation1 operation, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl1.ExecuteWriteOperation[TResult](IClientSessionHandle session, IWriteOperation1 operation, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl1.FindOneAndUpdate[TProjection](IClientSessionHandle session, FilterDefinition1 filter, UpdateDefinition1 update, FindOneAndUpdateOptions2 options, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl1.<>c__DisplayClass57_01.b__0(IClientSessionHandle session) at MongoDB.Driver.MongoCollectionImpl1.UsingImplicitSession[TResult](Func2 func, CancellationToken cancellationToken) at MongoDB.Driver.MongoCollectionImpl1.FindOneAndUpdate[TProjection](FilterDefinition1 filter, UpdateDefinition1 update, FindOneAndUpdateOptions2 options, CancellationToken cancellationToken) at SoPE.DbContext.UpdatePlanning(PlanningProjectUpdate projectUpdate, CancellationToken cancellationToken) in C:\projects\SOPE\sope-api\SolarPanelEstimation.Mongo\DbContext.cs:line 105 at SoPE.Estimation.MongoSolarPanelEstimationService.UpdatePlanning(PlanningProjectUpdate projectUpdate, CancellationToken cancellationToken) in C:\projects\SOPE\sope-api\SolarPanelEstimation.Mongo\Estimation\MongoSolarPanelEstimationService.cs:line 186 at SoPE.Controllers.V1_0.PlanningsController.UpdatePlanning(String id, UpdatePlanningProjectRequest model, CancellationToken cancellationToken) in C:\projects\SOPE\sope-api\SolarPanelEstimation.Api\Controllers\V1_0\PlanningsController.cs:line 90 at lambda_method542(Closure , Object ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Any ideas how I can fix this?