Reputation: 2872
I am porting some C# code from Microsoft.Azure.Documents to Microsoft.Azure.Cosmos. I created a small test case to try to get it working just accessing CosmosDB before testing it with my full application. I'll add my full code further below, but here is what I believe is the relevant content.
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);
}
Output looks like this:
Throughput: 400 Container props: Microsoft.Azure.Cosmos.ContainerProperties Error: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: {. Path '', line 1, position 1. at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType) at Newtonsoft.Json.JsonTextReader.ReadAsString() at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader) at Microsoft.Azure.Cosmos.CosmosJsonDotNetSerializer.FromStream[T](Stream stream) at Microsoft.Azure.Cosmos.CosmosJsonSerializerWrapper.FromStream[T](Stream stream) at Microsoft.Azure.Cosmos.CosmosSerializerCore.FromStream[T](Stream stream) at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.ToObjectpublic[T](ResponseMessage responseMessage) at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.b__8_0[T](ResponseMessage cosmosResponseMessage) at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.ProcessMessage[T](ResponseMessage responseMessage, Func`2 createResponse) at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.CreateItemResponse[T](ResponseMessage responseMessage) at Microsoft.Azure.Cosmos.ContainerCore.d__56`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Cosmos.ClientContextCore.d__38`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at TestCosmos_ns.TestCosmos_cl.d__3.MoveNext() in C:\Users\buchs\Work-NCS\TestCosmos2\TestCosmos\Program.cs:line 46
The documentDBstorageid is simply a string which matches the document ID found in the database. The database does not use partition keys. Obviously the container is fine as I can gather other data from it without exception.
Here is the fuller code
// 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}");
}
}
Upvotes: 0
Views: 2820
Reputation: 8690
Please try this:
use this code:
ItemResponse<JObject> result = await container.ReadItemAsync<JObject>(documentDBStorageId, PartitionKey.None, iro);
instead of:
ItemResponse<string> result = await container.ReadItemAsync<string>(documentDBStorageId, PartitionKey.None, iro);
Upvotes: 2
Reputation: 8783
It appears you are passing multiple values for id ("company", "companyid", "locationx")
You can only pass a single value for id for ReadItemAsync(). If you want to pass multiple values you can use a query with an IN() clause.
Upvotes: 0