.NET Core使用NetTopologySuite序列化FeatureCollection出现类型转换错误
异常触发原因
- 核心原因是待序列化的
FeatureCollection对象内部的集合元素类型与NetTopologySuite序列化器要求的强类型不匹配。绝大多数场景下是ASP.NET Core控制器接收GeoJSON请求体时,使用了默认的System.Text.Json反序列化,生成的Feature、Geometry对象类型不标准,内部的集合属性实际为object[]类型,序列化时无法转换为NetTopologySuite要求的Geometry[]、Feature[]等强类型数组,进而抛出类型转换异常。 - 次要原因可能是NetTopologySuite核心包与
NetTopologySuite.IO.GeoJSON包版本不兼容,或者序列化器未正确加载GeoJSON专用转换器。
解决方案
步骤1:配置控制器使用Newtonsoft.Json配套NetTopologySuite反序列化
在ASP.NET Core项目的启动配置(Program.cs)中添加Newtonsoft.Json的GeoJSON转换器配置,保证控制器接收的FeatureCollection是强类型标准对象:
// 先安装对应NuGet包: // Microsoft.AspNetCore.Mvc.NewtonsoftJson // NetTopologySuite.IO.GeoJSON builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new NetTopologySuite.IO.Converters.GeoJsonConverterFactory()); });
需要提前引用Newtonsoft.Json和NetTopologySuite.IO.Converters命名空间。
步骤2:修正序列化代码
可以直接使用配置好的序列化逻辑,无需手动创建序列化器,简化代码:
private async Task<IEnumerable<VehicleArea>> GetVehiclesInAreas(FeatureCollection areas) { var uri = $"www.someurl/getByArea"; using var httpClient = new HttpClient(); // 直接序列化即可,已自动加载GeoJSON转换器 string stringifiedAreas = JsonConvert.SerializeObject(areas); StringContent content = new StringContent(stringifiedAreas, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(uri, content); // 后续补充响应解析逻辑即可 }
临时修复方案(无需修改全局配置)
如果不方便修改全局反序列化配置,可以手动重建强类型的FeatureCollection后再序列化:
// 手动重建强类型FeatureCollection var strongTypeAreas = new FeatureCollection(); foreach (var originalFeature in areas) { var newFeature = new Feature(originalFeature.Geometry, originalFeature.Attributes) { Id = originalFeature.Id }; strongTypeAreas.Add(newFeature); } // 序列化重建后的对象即可 var stringifiedAreas = JsonConvert.SerializeObject(strongTypeAreas, new GeoJsonConverterFactory());
版本兼容检查
如果上述操作后仍报错,请将NetTopologySuite和NetTopologySuite.IO.GeoJSON两个NuGet包升级到最新稳定版本,避免版本不兼容问题。
内容的提问来源于stack exchange,提问作者Filip Skukan
相关产品推荐
相关产品推荐

