简体   繁体   中英

DynamoDB - Mapping Arbitrary C# Data Type With AWS SDK for .NET

I am attempting to persist a complex C# object into DynamoDB which looks like this.

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

The KycAttributes type property needs to be converted into a format DynamoDB accepts. Here is the Converter implementation from following this guide https://dotnetcodr.com/2015/02/02/using-amazon-dynamodb-with-the-aws-net-api-part-4-record-insertion/ :

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

Then, when DynamoDBContext.SaveAsync<User> is called, an exception with the following stacktrace is thrown:

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

Please note that the scenario is the following: this is an object that already exists in the database. However, that object did not have a kyc_attributes key and an attempt is being made to add that key to it. Is this possible? If so, how can the error be fixed?

In my case, the object I was trying to write to DynamoDB using Save was having HashKey set to null . I suppose this maybe also the cause of error when using SaveAsync .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM