c# - Microsoft.Azure.Cosmos.Container.ReadItemAsync() 失败 - json 解析 - 意外字符
问题描述
我正在将一些 C# 代码从 Microsoft.Azure.Documents 移植到 Microsoft.Azure.Cosmos。我创建了一个小测试用例,试图让它在使用我的完整应用程序测试它之前访问 CosmosDB。我将在下面进一步添加我的完整代码,但这是我认为相关的内容。
try {
Container container = client.GetContainer(DocumentDBDatabaseName, collectionId);
RequestOptions requestOptions = new RequestOptions();
ThroughputProperties tputprops = await container.ReadThroughputAsync(requestOptions);
Console.WriteLine($"Throughput: {tputprops.Throughput}");
ContainerProperties containerProperties = await container.ReadContainerAsync();
Console.WriteLine($"Container props: {containerProperties}");
// We don't use any partition keys, so use PartitionKey.None
ItemRequestOptions iro = new ItemRequestOptions();
ItemResponse<string> result = await container.ReadItemAsync<string>(documentDBStorageId, PartitionKey.None, iro);
return result; // successful return
} catch (CosmosException exc) {
Console.WriteLine("{0} error occurred: {1}", exc.StatusCode, exc);
} catch (Exception exc) {
Console.WriteLine("Error: {0}", exc);
}
输出如下所示:
吞吐量:400 容器道具:Microsoft.Azure.Cosmos.ContainerProperties 错误:Newtonsoft.Json.JsonReaderException:解析值时遇到意外字符:{。路径'',第 1 行,位置 1。 在 Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType) 在 Newtonsoft.Json.JsonTextReader.ReadAsString() 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader 阅读器,类型 objectType,布尔 checkAdditionalContent) 在 Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader 阅读器,类型 objectType) 在 Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader 阅读器) 在 Microsoft.Azure.Cosmos.CosmosJsonDotNetSerializer.FromStream[T](流流) 在 Microsoft.Azure.Cosmos.CosmosJsonSerializerWrapper.FromStream[T](流流) 在 Microsoft.Azure.Cosmos.CosmosSerializerCore.FromStream[T](流流) 在 Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.ToObjectpublic[T](ResponseMessage responseMessage) 在 Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.b__8_0[T](ResponseMessage cosmosResponseMessage) 在 Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.ProcessMessage[T](ResponseMessage responseMessage, Func`2 createResponse) 在 Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.CreateItemResponse[T](ResponseMessage responseMessage) 在 Microsoft.Azure.Cosmos.ContainerCore.d__56`1.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.Azure.Cosmos.ClientContextCore.d__38`1.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 在 C:\Users\buchs\Work-NCS\TestCosmos2\TestCosmos\Program.cs:line 46 中的 TestCosmos_ns.TestCosmos_cl.d__3.MoveNext()
documentDBstorageid 只是一个与数据库中找到的文档 ID 匹配的字符串。数据库不使用分区键。显然容器很好,因为我可以毫无例外地从中收集其他数据。
这是更完整的代码
// Package: Microsoft.Azure.Cosmos --version 3.12.0
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;
namespace TestCosmos_ns
{
class TestCosmos_cl
{
private static string DocumentDBDatabaseName = "mydbname";
public static void Main(string[] args)
{
Task Ta = AsyncMain(args);
Ta.Wait(); // Wait for all async tasks to close.
}
public static async Task AsyncMain(string[] args)
{
// corresponds to CosmosDB container
string EmployeeCollection = "directory";
string docId2 = GetDocumentDBStorageId("company", "companyid", "locationx");
string u = await GetDocumentById(EmployeeCollection, docId2);
Console.WriteLine("GetDocumentById returns:");
Console.WriteLine(u);
bool v = DocumentExists(EmployeeCollection, docId2);
Console.WriteLine("DocumentExists() returns:");
Console.WriteLine(v);
}
public static async Task<string> GetDocumentById(string collectionId, string documentDBStorageId)
{
CosmosClient client = GetDocumentDBClient();
try {
Container container = client.GetContainer(DocumentDBDatabaseName, collectionId);
RequestOptions requestOptions = new RequestOptions();
ThroughputProperties tputprops = await container.ReadThroughputAsync(requestOptions);
Console.WriteLine($"Throughput: {tputprops.Throughput}");
ContainerProperties containerProperties = await container.ReadContainerAsync();
Console.WriteLine($"Container props: {containerProperties}");
// We don't use any partition keys, so use PartitionKey.None
ItemRequestOptions iro = new ItemRequestOptions();
ItemResponse<string> result = await container.ReadItemAsync<string>(documentDBStorageId, PartitionKey.None, iro);
return result; // successful return
} catch (CosmosException exc) {
Console.WriteLine("{0} error occurred: {1}", exc.StatusCode, exc);
} catch (Exception exc) {
Console.WriteLine("Error: {0}", exc);
}
return ""; // return in exception situations
}
public static bool DocumentExists(string collectionId, string documentDBStorageId)
{
// OK, totally cheating. Just try to retrieve the document, if we get back blank, then there
// was an exception and it doesn't exist.
Task<string> getResult = GetDocumentById(collectionId, documentDBStorageId);
getResult.Wait();
string result = getResult.Result;
if (result.Length == 0) {
return false;
}
return true;
}
private static CosmosClient TheCosmosClient = null;
public static CosmosClient GetDocumentDBClient()
{
string DocumentDBEndpointUrl = "https://mydb.documents.azure.com:443/";
string DocumentDBPrimaryKey = "myprimarykey...==";
TheCosmosClient = TheCosmosClient ?? new CosmosClient(DocumentDBEndpointUrl, DocumentDBPrimaryKey);
return TheCosmosClient;
}
private static string NormalizePath(string result)
{
string toReplace = " ,.<>?;:'\"`~!@#$%^&*()-=+";
foreach (char c in toReplace)
result = result.Replace(c, '_');
result = result.Replace("__", "_");
return result;
}
public static string GetDocumentDBStorageId(string companyName, string companyId, string locationName) => NormalizePath($"Employees_{companyName}_{companyId}_{locationName}");
}
}
解决方案
请试试这个:
使用此代码:
ItemResponse<JObject> result = await container.ReadItemAsync<JObject>(documentDBStorageId, PartitionKey.None, iro);
代替:
ItemResponse<string> result = await container.ReadItemAsync<string>(documentDBStorageId, PartitionKey.None, iro);
推荐阅读
- javascript-engine - 为什么 DevTools 中出现这种类型的错误 failed to load SourceMap
- scala - 使用其他现有列 Spark/Scala 添加新列
- c# - 集合项的 FluentValidator
- javascript - Vue路由器视图未显示所有视图
- bash - 如何在 bash 中以多字符串开头的每一行剪切所有内容?
- python - 另一个模型中的 Django Rest 访问模型值
- authentication - Heroku 登录不接受我的 Authy 生成的身份验证器代码
- firebase - Android 4.4 上的 ReactNative Firestore 崩溃
- pdf - 文本标签无法正确显示 DataStudio
- javascript - TypeScript:如何将文件导入 index.ts 而不会获得未定义的数据