我试图将一个复杂的C#对象持久保存到DynamoDB中,如下所示。
[DynamoDBTable("some_table")]
public class User
{
[DynamoDBHashKey]
public string user_id { get; set; }
[DynamoDBRangeKey]
public string client_name { get; set; }
public string client_location { get; set; }
public DateTime signup_date { get; set; }
[DynamoDBProperty(typeof(KycConverter))]
public KycAttributes kyc_attributes { get; set; }
}
public class KycAttributes
{
public string kyc_id { get; set; }
}
KycAttributes类型属性需要转换为DynamoDB接受的格式。这是遵循本指南https://dotnetcodr.com/2015/02/02/using-amazon-dynamodb-with-the-aws-net-api-part-4-record-insertion/的Converter实现:
public class KycConverter : IPropertyConverter
{
public object FromEntry(DynamoDBEntry entry)
{
Primitive primitive = entry as Primitive;
if (primitive == null) return new KycAttributes();
if (primitive.Type != DynamoDBEntryType.String)
{
throw new InvalidCastException(string.Format("KycAttributes cannot be converted as its type is {0} with a value of {1}"
, primitive.Type, primitive.Value));
}
string json = primitive.AsString();
return JsonConvert.DeserializeObject<KycAttributes>(json);
}
public DynamoDBEntry ToEntry(object value)
{
Trace.TraceInformation("Invoked");
KycAttributes attributes = value as KycAttributes;
if (attributes == null) return null;
string json = JsonConvert.SerializeObject(attributes);
return new Primitive(json);
}
}
然后,在调用DynamoDBContext.SaveAsync<User>
时,将引发带有以下堆栈跟踪的异常:
Object reference not set to an instance of an object.
at Amazon.DynamoDBv2.Model.Internal.MarshallTransformations.AttributeValueMarshaller.Marshall(AttributeValue requestObject, JsonMarshallerContext context) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Services\DynamoDBv2\Generated\Model\Internal\MarshallTransformations\AttributeValueMarshaller.cs:line 48
at Amazon.DynamoDBv2.Model.Internal.MarshallTransformations.UpdateItemRequestMarshaller.Marshall(UpdateItemRequest publicRequest) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Services\DynamoDBv2\Generated\Model\Internal\MarshallTransformations\UpdateItemRequestMarshaller.cs:line 165
at Amazon.Runtime.Internal.Marshaller.PreInvoke(IExecutionContext executionContext) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Pipeline\Handlers\Marshaller.cs:line 79
at Amazon.Runtime.Internal.Marshaller.InvokeAsync[T](IExecutionContext executionContext) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Pipeline\Handlers\Marshaller.cs:line 51
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Core\Amazon.Runtime\Pipeline\Handlers\CallbackHandler.cs:line 60
at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.DynamoDBv2.DocumentModel.Table.UpdateHelperAsync(Document doc, Key key, UpdateItemOperationConfig config, CancellationToken cancellationToken) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Services\DynamoDBv2\Custom\DocumentModel\Table.cs:line 871
at Amazon.DynamoDBv2.DataModel.DynamoDBContext.SaveHelperAsync[T](T value, DynamoDBOperationConfig operationConfig, CancellationToken cancellationToken) in D:\JenkinsWorkspaces\trebuchet-stage-release\AWSDotNetPublic\sdk\src\Services\DynamoDBv2\Custom\DataModel\Context.cs:line 285
请注意,方案如下:这是数据库中已经存在的对象。但是,该对象没有kyc_attributes键,并且正在尝试将该键添加到其中。这可能吗?如果是这样,如何解决错误?