So I’m trying to serialize/deserialize from DynamoDb Table Property (Dictionary< string,object> Payload {get;set;}) with the idea that the Key would be the Type, and the Value would be the object to serialize.
Example:
I can serialize into DynamoDb no problem, and looking at the above example, it looks fine. The Payload has one type (JobRequestor) and the properties of JobRequestor are there.
I’m having problems deserializing back out because the data comes back encoded as Amazon AttributeValues which throw an error trying to use .FromObjectDictionary< AttributeValuie>()
{
"Enumis.Api.Jobs.ServiceModel.Types.JobRequestor": {
"ApprovalState": {
"__type": "Amazon.DynamoDBv2.Model.AttributeValue, AWSSDK.DynamoDBv2",
"bool": false,
"isBOOLSet": false,
"bs": [],
"l": [],
"isLSet": false,
"m": {},
"isMSet": false,
"ns": [],
"null": false,
"s": "Pending",
"ss": []
},
"RequestedCognitoEmail": {
"bool": false,
"isBOOLSet": false,
"bs": [],
"l": [],
"isLSet": false,
"m": {},
"isMSet": false,
"ns": [],
"null": false,
"s": "you@wish.com",
"ss": []
}
}
}
I am trying to create a generic PayloadDeserializer that looks at the root object containing the Payload dictionary, and if any properties on this root object match the type in the Payload dictionary keys, deserialize the object back into the property on the root object.
My current attempt looks something like this (keep in mind I’m just trying to work the process out here):
var genericJob = ServiceClient.Get(new JobRequest {ERN = "ern::Enumis::GpsCreateCardsJob::8a24cfc0-d326-4de7-8534-812b92f89d8b"});
var _job = genericJob.ConvertTo<ApprovalJob>();
var requestor = _job.Payload[typeof(JobRequestor).FullName] as Dictionary<string,object>;
var state = requestor["ApprovalState"] as Dictionary<string, object>;
var attr = state.FromObjectDictionary<AttributeValue>();
Which when I run I get the following error:
System.IndexOutOfRangeException : Index was outside the bounds of the array.
at System.String.get_Chars(Int32 index)
at ServiceStack.StringExtensions.ToPascalCase(String value)
at ServiceStack.PlatformExtensions.FromObjectDictionary(IReadOnlyDictionary`2 values, Type type)
at ServiceStack.PlatformExtensions.FromObjectDictionary[T](IReadOnlyDictionary`2 values)
at Enumis.Api.Jobs.Tests.IntegrationTest.Can_Serialize_Deserialize_Payload() in D:\Dev\enumis.api.jobs\src\Enumis.Api.Jobs.Tests\IntegrationTest.cs:line 70
This seems to be caused by the property
"__type": "Amazon.DynamoDBv2.Model.AttributeValue, AWSSDK.DynamoDBv2",
When I remove the __type from the dictionary, I can get a little farther, but it still blows up on the property:
"m": {},
With the following error:
System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.Dictionary`2[System.String,Amazon.DynamoDBv2.Model.AttributeValue]' to type 'System.Collections.Generic.ICollection`1[System.String]'.
at ServiceStack.Text.TranslateListWithConvertibleElements`2.TranslateToGenericICollection(ICollection`1 fromList, Type toInstanceOfType)
at ServiceStack.Text.TranslateListWithConvertibleElements`2.LateBoundTranslateToGenericICollection(Object fromList, Type toInstanceOfType)
at ServiceStack.Text.TranslateListWithElements.TranslateToConvertibleGenericICollectionCache(Object from, Type toInstanceOfType, Type fromElementType)
at ServiceStack.Text.TranslateListWithElements.TryTranslateCollections(Type fromPropertyType, Type toPropertyType, Object fromValue)
at ServiceStack.TypeConverter.<>c__DisplayClass0_0.<CreateTypeConverter>b__4(Object fromValue)
at ServiceStack.PlatformExtensions.ObjectDictionaryFieldDefinition.SetValue(Object instance, Object value)
at ServiceStack.PlatformExtensions.FromObjectDictionary(IReadOnlyDictionary`2 values, Type type)
at ServiceStack.PlatformExtensions.FromObjectDictionary[T](IReadOnlyDictionary`2 values)
at Enumis.Api.Jobs.Tests.IntegrationTest.Can_Serialize_Deserialize_Payload() in D:\Dev\enumis.api.jobs\src\Enumis.Api.Jobs.Tests\IntegrationTest.cs:line 71
Question: What is the best way to achieve this, and how can I deserialize this data back into the concrete property type it should be?