1
votes

below is the code that I do pagination in Azure Cosmos. In that function I return the ContinuationToken of the FeedResponse. The first request to get the first page is fine and it return the Continuation Token. However if I used that token in the next request then the API return error 500.

I also notice that the ContinuationToken return from FeedRespone seem like in Json format like that. I have tried to get the token section only, or even copy the whole json but no cigar though

"nextToken": "[{"token":"+RID:~UVURALkfIb4FAAAAAAAAAA==#RT:1#TRC:3#RTD:hCgamV5sp6dv/pVR3z0oBTMxMzIuMTQuNDFVMTY7MjY7NDIvOTk3MzIxMlsA#ISV:2#IEO:65567#QCF:1#FPC:AQEAAAAAAAAACAAAAAAAAAA=","range":{"min":"","max":"FF"}}]"

Response from the First Page with Token return Response from the  First Page with Token return Enter Return Token to next request and error 500 Enter Return Token to next request and error 500

Function Code

public virtual async Task<(IEnumerable<TDomain>, string token)> ListAsync(List<ISpecification<TEntity>> specifications, PageOptions pageOptions, CancellationToken cancellationToken)
        {
            var container = await GetContainer(cancellationToken);
            string token = null;
            var result = new List<TDomain>();
            QueryRequestOptions options = new QueryRequestOptions()
            {
                MaxItemCount = pageOptions.MaxResults
            };
            options.MaxItemCount = pageOptions.MaxResults;
            try
            {

                var query = container
                    .GetItemLinqQueryable<TEntity>(false, pageOptions.NextToken, options)
                    .Specify(specifications);

                var iterator = _cosmosLinqQuery.GetFeedIterator(query);

     
                    var response = await iterator.ReadNextAsync(cancellationToken);
                    token = response.ContinuationToken; // return a token
                    foreach (var item in response)
                    {
                        var mapped = _mapper.ToDomain(item);
                        result.Add(mapped);
                    }
      
            }
            catch (Exception ex)
            {
                var exception = new DataAccessException("Unexpected error while listing items", ex);
                exception.Data["ContainerName"] = ContainerName;
                throw exception;
            }

            return (result,token);
        }
1

1 Answers

1
votes

Your second screenshot is showing that you are passing a token that starts with +RID... which is not how the previous token starts (previous token starts with [{"token").

Could you be dropping the JSON wrapping attributes that are part of the token?

The second call should be passing exactly [{"token":"+RID:~UVURALkfIb4FAAAAAAAAAA==#RT:1#TRC:3#RTD:hCgamV5sp6dv/pVR3z0oBTMxMzIuMTQuNDFVMTY7MjY7NDIvOTk3MzIxMlsA#ISV:2#IEO:65567#QCF:1#FPC:AQEAAAAAAAAACAAAAAAAAAA=","range":{"min":"","max":"FF"}}]. Keep in mind that you are also sending it in the URL, so there might be character escaping there too.