问题描述
我正在尝试将地理空间数据存储在名为 Trips 的 Cosmos db 容器中,并从我的 .net core web api (.net 5) 中检索项目。我正在使用 Microsoft.Azure.Cosmos (3.19.0) 并且没有为序列化明确配置任何内容。保存有效,但当我尝试检索时出现此错误:
Newtonsoft.Json.JsonSerializationException:无法反序列化 Geometry 对象,因为“type”属性不存在或值无效。
Cosmos 客户端实例:
var options = new CosmosClientOptions()
{
AllowBulkExecution = true,SerializerOptions = new CosmosSerializationoptions()
{
PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
}
};
var cosmosClient = new CosmosClient(account,key,options);
型号:
public class Trip
{
[JsonPropertyName("id"),required]
public string Id { get; set; }
[JsonPropertyName("vehicleId"),required]
public string VehicleId { get; set; }
[JsonPropertyName("startDateTime"),required]
public DateTime StartDateTime { get; set; }
[JsonPropertyName("endDateTime"),required]
public DateTime EndDateTime { get; set; }
[JsonPropertyName("wayPoints"),required]
public List<WayPoint> WayPoints { get; set; }
}
public class WayPoint
{
[JsonPropertyName("timeStamp"),required]
public DateTime TimeStamp { get; set; }
[JsonPropertyName("point"),required]
public Point Point { get; set; }
}
服务:
public async Task<IEnumerable<Trip>> GetMultipleAsync(string vehicleId = "")
{
var queryDeFinition = new QueryDeFinition($"Select * from c where c.vehicleId = \"{vehicleId}\"");
var queryIterator = _container.GetItemQueryIterator<Trip>(queryDeFinition);
var trips = new List<Trip>();
while(queryIterator.HasMoreResults)
{
var response = await queryIterator.ReadNextAsync();
trips.AddRange(response.ToList());
}
return trips;
}
控制器:
using FileStream createStream = System.IO.File.Create(@"C:\repos\TripGenerator\trips.json");
await JsonSerializer.SerializeAsync(
createStream,trips);
Json 示例:
{
"id": "a9153ca0-e171-4fe8-bcfe-733ac75f6b85","vehicleId": "599abc63-eafb-4015-ac65-fc6aed48d9aa","startDateTime": "2021-06-17T00:00:00Z","endDateTime": "2021-06-17T23:55:00Z","wayPoints": [
{
"timeStamp": "2021-06-17T00:00:00Z","point": {
"Position": {
"Coordinates": [
51.23156579100001,-0.603818000999999
],"Longitude": 77.23156579100001,"Latitude": 12.016038180009999,"Altitude": null
},"Crs": {
"Type": 0
},"Type": 0,"BoundingBox": null,"AdditionalProperties": {}
}
},{
"timeStamp": "2021-06-17T00:05:00Z","point": {
"Position": {
"Coordinates": [
51.23159449100001,-0.01703846700999
],"Longitude": 77.23159449100001,"Latitude": 12.603846700999998,////////////
{
"timeStamp": "2021-06-17T23:55:00Z","point": {
"Position": {
"Coordinates": [
51.23980269100042,-0.01961205490099
],"Longitude": 77.23980269100042,"Latitude": 12.612054900999901,"AdditionalProperties": {}
}
}
],}
任何帮助将不胜感激。谢谢!
解决方法
问题似乎出在您使用的套管配置上:
PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
您的 Json 显示“Point”的“Type”属性存在,但错误中的大小写显示“type”(小写 T)。
V3 SDK (https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos/src/Spatial/Geometry.cs#L70) 中的 Geometry 类型将 Type 定义为“type”:
[DataMember(Name = "type")]
[JsonProperty("type",Required = Required.Always,Order = 0)]
[JsonConverter(typeof(StringEnumConverter))]
public GeometryType Type { get; private set; }
所以通常我们希望它被序列化/保存为“类型”,而不是“类型”。
PropertyNamingPolicy 在保存文档时将其序列化为“Type”,或者使用不同的 SDK/工具保存文档,该 SDK/工具将几何体序列化为“Type”。
这就是抛出这个异常的原因。