CosmosDBTrigger does not work properly with Graph model. GetPropertyValue<T> errors.
See original GitHub issueI have a Cosmos graph database (Gremlin.NET) and want to use Azure Functions with CosmosDBTrigger to utilize Change Feed but when I use Document.GetPropertyValue<T> I get a System.ArgumentException.
Repro steps
The following code errors on GetPropertyValue method call.
public static async Task Run([CosmosDBTrigger(
databaseName: "MyDB",
collectionName: "MyGraph",
ConnectionStringSetting = "CosmosConnectionString",
LeaseCollectionName = "Leases"
)]IReadOnlyList<Document> documents, ILogger log)
{
if (documents != null && documents.Count > 0)
{
foreach (var document in documents)
{
var lastName = document.GetPropertyValue<string>("lastName");
}
}
}
Expected behavior
Variable ‘lastName’ should be populated with string.
Actual behavior
System.ArgumentException thrown with message “Can not convert Array to String.”
Stacktrace…
at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType)
at Newtonsoft.Json.JsonTextReader.ReadAsString()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
Known workarounds
The only way I can get around this is to parse the object myself e.g. use JArray but that makes life hard and defeats the point of using Azure Functions Cosmos trigger.
I have also tried doing a ToString on the document object and deserialise like so…
var user = JsonConvert.DeserializeObject<User>(document.ToString());
The document.ToString() provides the following json…
"{
"label": "user",
"firstName": [
{
"_value": "Johnny",
"id": "d0d8dbbc-8263-4f61-9bc1-60f8bcbd2c11"
}
],
"lastName": [
{
"_value": "Roberts",
"id": "4a9e7f89-21a4-4424-859c-393400335695"
}
],
"userName": [
{
"_value": "jroberts10",
"id": "3ed45581-e29f-404a-a75d-3279f5c48425"
}
],
"userStatus": [
{
"_value": "\\"GraphOnly\\"",
"id": "d7fe7a21-979b-4633-9b5e-92c8f8331d72"
}
],
"primaryEmailAddress": [
{
"_value": "jroberts@sivers.co.uk",
"id": "5e13a000-6cf0-4413-b4fe-ea51d1c0bd2a"
}
],
"dateOfBirth": [
{
"_value": "01/01/0001 00:00:00",
"id": "dd7556e4-9b08-4519-bdf8-aa94e92896a6"
}
],
"isCoach": [
{
"_value": "False",
"id": "c3140fbb-4047-4cfe-a985-b810b25a5e84"
}
],
"id": "7b0c7dcd-e3df-4ee3-b324-1b8c009788a7",
"createdDate": [
{
"_value": "11/02/2019 00:09:58",
"id": "7644d23b-20c3-42a9-a40d-baa5357ee9df"
}
],
"partitionKey": "user",
"documentType": [
{
"_value": "user",
"id": "54aed62e-f607-450e-ab39-054a3d567a22"
}
],
"_rid": "Ix4TAMcT9pCZAAAAAAAAAA==",
"_self": "dbs/Ix4TAA==/colls/Ix4TAMcT9pA=/docs/Ix4TAMcT9pCZAAAAAAAAAA==/",
"_etag": "\\"00003b39-0000-0000-0000-5c60bd570000\\"",
"_attachments": "attachments/",
"_ts": 1549843799,
"_lsn": 224,
"_metadata": {}
}"
Related information
Package reference…
<PackageReference Include="Gremlin.Net" Version="3.4.*" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.CosmosDB" Version="3.0.*" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventGrid" Version="2.0.*" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.*" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
@ealsur Just created this extension method to make it nice and easy in the meantime!
@msivers I totally agree and it should be more easy for non-Core API accounts to consume the Trigger. We’ll work on adding more type binding support for those scenarios.