目前,我尝试在 Cosmos db 中获取查询的下一个结果,这是我的代码。
public async Task<KeyValuePair<string, IEnumerable<Peterworks>>> GetMultipleAsyncPaging(string queryString, string continuesToken,
int pageSize)
{
var results = new List<Peterworks>();
QueryRequestOptions queryRequestOptions = new QueryRequestOptions();
queryRequestOptions.MaxItemCount = pageSize;
var query = _container.GetItemQueryIterator<Peterworks>(new QueryDefinition(queryString), continuesToken, queryRequestOptions);
FeedResponse<Peterworks> feedResponse = await query.ReadNextAsync();
foreach (Peterworks peterworks in feedResponse)
{
results.Add(peterworks);
}
return new KeyValuePair<string, IEnumerable<Peterworks>>(feedResponse.ContinuationToken, results);
}
将此代码与 Asp.net core Web api 结合使用
API
public async Task<IActionResult> GetPageResult(string appkey, string postbackType, long startDate, long endDate, int pagesize, string continuetoken)
{
KeyValuePair<string, IEnumerable<Peterworks>> returnValue;
int pageNumber = 0;
var query =
$"SELECT * FROM peter_db p where p.appkey = '{appkey}'AND p.postback_type = '{postbackType}' AND p.event_time >= {startDate} AND p.event_time <= {endDate} ORDER BY p.event_time";
if (continuetoken == "null")
{
string continueNullToken = null;
returnValue =
await _cosmosDbService.GetMultipleAsyncPaging(query, continueNullToken, pagesize);
}
else
{
string continueTokenDecode = HttpUtility.UrlDecode(continuetoken);
var jsonContiueToken = JsonConvert.SerializeObject(continueTokenDecode);
returnValue =
await _cosmosDbService.GetMultipleAsyncPaging(query, jsonContiueToken, pagesize);
}
return Ok(returnValue);
}
当 token 为空时,我得到这个结果
{ "key": "[{\"token\":\"+RID:~6XYNAPAaNywkAQAAAAAAAA==#RT:1#TRC:2#RTD:EOhlC3LmlrnZoy5QrRcNBMHZH43PLA==#ISV:2#IEO:65567#QCF:7#FPC:AgEAAAAyAK8A4Hf99T7xxMAf+QH8/AF/APwPeEB/nWZk+H8A8H8ACMAA8P//A5Dw///f/v////8B\",\"range\":{\"min\":\"\",\"max\":\"FF\"}}]",
使用此标记值,我尝试获取下一个结果,但出现了此错误。
Microsoft.Azure.Cosmos.Query.Core.Exceptions.MalformedContinuationTokenException: Invalid format for continuation token "[{\\\"token\\\":\\\" RID:~6XYNAPAaNywkAQAAAAAAAA==#RT:1#TRC:2#RTD:EOhlC3LmlrnZoy5QrRcNBMHZH43PLA==#ISV:2#IEO:65567#QCF:7#FPC:AgEAAAAyAK8A4Hf99T7xxMAf QH8/AF/APwPeEB/nWZk H8A8H8ACMAA8P//A5Dw///f/v////8B\\\",\\\"range\\\":{\\\"min\\\":\\\"\\\",\\\"max\\\":\\\"FF\\\"}}]" for ParallelCrossPartitionQueryPipelineStage
没有jsonConvert,就出现了这个错误。
Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: f1a36b17-58de-44f9-9d73-ba699c38bb16; Reason: (Encountered an unexpected JSON token.ActivityId: f1a36b17-58de-44f9-9d73-ba699c38bb16, Darwin/10.16 cosmos-netstandard-sdk/3.19.3);
我错过了什么?
最佳答案
在 ASP.NET Core 中,我用来使连续 token 作为 URL 参数安全地进行往返的方法是利用 Base64UrlEncode
。
在返回客户端之前进行编码:
using Microsoft.AspNetCore.WebUtilities;
...
string continuationToken = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(cosmosToken));
在客户端提供时进行解码:
// Decode continuation token if provided
string? currentContinuationToken = !string.IsNullOrEmpty(continuationToken)
? Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(continuationToken))
: null;
关于c# - Cosmos db 上的延续 token 格式无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68633504/