【问题标题】:Dictionary serialization for DynamoDB ExclusiveStartKey not workingDynamoDB ExclusiveStartKey 的字典序列化不起作用
【发布时间】:2021-01-18 12:27:00
【问题描述】:

对于来自 Dynamo 的分页响应,我试图保留 ExclusiveStartKey 值。在代码示例中,如果我直接使用response.LastEvaluatedKey 值,后续请求工作正常。

但是,如果我序列化 response.LastEvaluatedKey,然后将其序列化回用作 ExclusiveStartKey 值,则后续请求将失败并显示以下错误消息:

提供的起始键无效:一个或多个参数值无效:Null 属性值类型的值必须为 true

反序列化的字典似乎与原始字典具有相同的值...有什么要检查的,看看两者之间有什么不同吗?

QueryResponse response = null;

do
{

    string gsiPartitionKey = "gsi-pk-value-1";

    var queryRequest = new QueryRequest()
    {
        TableName = "my-table",
        IndexName = "my-index",
        KeyConditionExpression = "IndexPk = :s_gsiPartitionKey",
        ExpressionAttributeValues = new Dictionary<string, AttributeValue>
        {
            {
                ":s_gsiPartitionKey", new AttributeValue { S = gsiPartitionKey}
            }
        },
        Limit = 1
    };

    if (response != null)
    {
        //OPTION 1 - OK - Using LastEvaluatedKey directly works fine
        //queryRequest.ExclusiveStartKey = response.LastEvaluatedKey;

        //OPTION 2 - BAD - Serializing and deserializing  fails
        var serialized = JsonConvert.SerializeObject(response.LastEvaluatedKey);
        var deserialized = JsonConvert.DeserializeObject<Dictionary<string, AttributeValue>>(serialized);
        queryRequest.ExclusiveStartKey = deserialized;
    }

    response = await DynamoDbClient.QueryAsync(queryRequest);

} while (response.LastEvaluatedKey.Count != 0);

【问题讨论】:

    标签: c# dictionary serialization amazon-dynamodb jsonconvert


    【解决方案1】:

    我今天遇到了这个问题,并认为我会更新它。 在AttributeValue 类中,有一个bool? 类型的非公共成员_null 在从JSON 反序列化时被错误地初始化。 当它应该设置为null时,它被设置为false

    使用反射,在反序列化之后,我将字典中每个键的值设置为 null,AWS 现在按预期返回数据。

    为了访问私有成员,我使用了这个函数:

    public void SetPrivatePropertyValue<T>(object obj, string propName, T val)
    {
        Type t = obj.GetType();
    
        // add a check here that the object obj and propertyName string are not null
        foreach (FieldInfo fi in obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
        {
            if (fi.Name.ToLower().Contains(propName.ToLower()))
            {
                fi.SetValue(obj, val);
                break;
            }
        }
    }
    

    方法调用是 SetPrivatePropertyValue&lt;bool?&gt;(attribute, "_null", null);

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-28
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      相关资源
      最近更新 更多