目前我有一个类存储在 Cosmos DB 中。该类有一个接口作为成员变量。当我尝试查询并迭代结果时,出现异常。
public class Group
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "partitionKey")]
public string PartitionKey { get; set; }
public IResult Result;
}
然后是我的代码来检索这些对象。
var getAllGroupObjects = $"SELECT *\r\nFROM c\r\nWHERE c.id IN (\"{string.Join("\",\"", currentGroupIds)}\")";
QueryDefinition getAllGroupsQuery = new QueryDefinition(getAllGroupObjects);
FeedIterator<Group> allGroupsSetIterator = this.container.GetItemQueryIterator<Group>(getAllGroupsQuery);
List<Group> allGroups = new List<Group>();
while (allGroupsSetIterator.HasMoreResults)
{
var currentResultSet2 = await allGroupsSetIterator.ReadNextAsync();
foreach (Group l in currentResultSet2)
{
allGroups.Add(l);
}
}
我从 Newtonsoft.Json 得到以下异常
Error: Newtonsoft.Json.JsonSerializationException: Could not create an instance of type Shared.Types.IResult. Type is an interface or abstract class and cannot be instantiated. Path '[1].TotalPoints', line 1, position 3298.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
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.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 creator, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
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.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 creator, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
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.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(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.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.FromFeedStream[T](Stream stream)
at Microsoft.Azure.Cosmos.Serializer.CosmosElementSerializer.GetResourcesHelper[T](IReadOnlyList`1 cosmosElements, CosmosSerializerCore serializerCore, CosmosSerializationFormatOptions cosmosSerializationOptions)
at Microsoft.Azure.Cosmos.Serializer.CosmosElementSerializer.GetResources[T](IReadOnlyList`1 cosmosArray, CosmosSerializerCore serializerCore)
at Microsoft.Azure.Cosmos.QueryResponse`1..ctor(HttpStatusCode httpStatusCode, IReadOnlyList`1 cosmosElements, CosmosQueryResponseMessageHeaders responseMessageHeaders, CosmosDiagnostics diagnostics, CosmosSerializerCore serializerCore, CosmosSerializationFormatOptions serializationOptions, RequestMessage requestMessage)
at Microsoft.Azure.Cosmos.QueryResponse`1.CreateResponse[TInput](QueryResponse cosmosQueryResponse, CosmosSerializerCore serializerCore)
at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.CreateQueryFeedResponseHelper[T](ResponseMessage cosmosResponseMessage)
at Microsoft.Azure.Cosmos.CosmosResponseFactoryCore.CreateQueryFeedUserTypeResponse[T](ResponseMessage responseMessage)
at Microsoft.Azure.Cosmos.FeedIteratorCore`1.ReadNextAsync(ITrace trace, CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.ClientContextCore.RunWithDiagnosticsHelperAsync[TResult](String containerName, String databaseName, OperationType operationType, ITrace trace, Func`2 task, Func`2 openTelemetry, String operationName, RequestOptions requestOptions)
at Microsoft.Azure.Cosmos.ClientContextCore.<>c__DisplayClass31_0`1.<<OperationHelperWithRootTraceWithSynchronizationContextAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
我的 IResult 对象是一个接口,可以由几种类型的类之一实现。有没有办法让 CosmosDB 在让这个迭代器遍历这些已实现接口的对象时不恐慌?
尝试添加自定义 JsonConverter:
[JsonProperty(PropertyName = "result")]
[JsonConverter(typeof(ResultConverter))]
public IResult Result { get; set; }
看看如何编写 JsonConverter: CosmosClient :自定义 json 转换器可以与 NewtonSoft 一起使用,而不是与 System.Text.Json 一起使用