C# .Net Core 5使用GDAL包发布到IIS执行Ogr.RegisterAll()报错
问题场景
使用Visual Studio 2019创建.NET Core 5 Web应用,项目中引入GDAL相关依赖包,本地调试运行无异常,发布部署到IIS后触发错误。引入的GDAL包参考如下截图:
业务代码
public IActionResult GetLayerInfo(string fileName) { var path = Path.Combine( Directory.GetCurrentDirectory(), @"wwwroot\files\import", fileName); List<string> fList = new List<string>(); GdalConfiguration.ConfigureGdal(); GdalConfiguration.ConfigureOgr(); Ogr.RegisterAll(); DataSource sDatasource = Ogr.Open(path, 1); if (sDatasource == null) return null; OSGeo.OGR.Layer sLayer = sDatasource.GetLayerByIndex(0); FeatureDefn srcVectorDefn = sLayer.GetLayerDefn(); var type = srcVectorDefn.GetGeomType(); var geomType = wkbGeometryType.GetName(type); var spatialReference = sLayer.GetSpatialRef(); long fcount = sLayer.GetFeatureCount(1); var epsg = spatialReference.GetAttrValue("AUTHORITY", 1); for (int i = 0; i < srcVectorDefn.GetFieldCount(); i++) { FieldDefn fieldDefn = srcVectorDefn.GetFieldDefn(i); fList.Add(fieldDefn.GetName()); } sDatasource.Dispose(); return Json(new { fCount = fcount, epsg = epsg, geomType = geomType.Replace("wkb", ""), fList = fList, tName = Path.GetFileNameWithoutExtension(fileName) }); }
报错信息
错误在执行Ogr.RegisterAll();行时触发,抛出的异常信息如下:
An unhandled exception occurred while processing the request. NotSupportedException: Serialization and deserialization of 'System.Type' instances are not supported and should be avoided since they can lead to security issues. System.Text.Json.Serialization.Converters.TypeConverter.Write(Utf8JsonWriter writer, Type value, JsonSerializerOptions options) NotSupportedException: Serialization and deserialization of 'System.Type' instances are not supported and should be avoided since they can lead to security issues. Path: $.error.TargetSite.DeclaringType. System.Text.Json.ThrowHelper.ThrowNotSupportedException(ref WriteStack state, NotSupportedException ex)
问题原因
看到的序列化报错不是根因,是两层异常叠加的结果:
- 根因是IIS环境下GDAL初始化失败:本地调试时VS会自动将GDAL依赖的非托管原生dll、配置文件拷贝到运行目录,发布到IIS时大概率出现原生依赖缺失、架构不匹配、权限不足、路径配置错误等问题,导致
Ogr.RegisterAll()执行时先抛出原生库加载失败的底层异常。 - 表层的System.Text.Json序列化错误是次生问题:.NET Core默认的异常处理中间件会尝试把捕获到的异常对象序列化为JSON返回,而异常对象的
TargetSite.DeclaringType属性属于System.Type类型,System.Text.Json默认出于安全考虑不支持序列化该类型,就会覆盖掉原始的GDAL加载异常,最终看到的是序列化失败的报错,而非真正的根错误。
解决步骤
- 先排除序列化干扰拿到真实错误:在
Ogr.RegisterAll();外层增加try-catch块,捕获异常后直接记录异常的Message、InnerException内容到日志或临时响应中,不要让框架默认序列化完整异常对象,此时一般能看到真实错误,绝大多数是“无法加载dll gdal_wrap:找不到指定模块”这类原生库加载提示。 - 修复GDAL原生库部署问题
- 确认发布时勾选了生成原生依赖,发布完成后检查部署目录,确认存在和IIS应用池架构匹配(x86/x64必须严格一致,建议统一用x64,对应关闭应用池“启用32位应用”选项)的GDAL原生dll(包括gdal核心库、ogr库、proj投影库、gdal_wrap托管包装库等),如果缺失直接把本地bin目录下对应runtime的原生文件拷贝到部署目录根路径,或
runtimes/win-x64/native目录下。 - 给IIS部署目录授予
IIS_IUSRS用户组读取、执行权限,避免应用池身份无权限加载原生dll。 - 打开IIS对应应用池的高级设置,将加载用户配置文件选项设为
True,避免GDAL初始化时查找临时路径、配置路径失败。
- 确认发布时勾选了生成原生依赖,发布完成后检查部署目录,确认存在和IIS应用池架构匹配(x86/x64必须严格一致,建议统一用x64,对应关闭应用池“启用32位应用”选项)的GDAL原生dll(包括gdal核心库、ogr库、proj投影库、gdal_wrap托管包装库等),如果缺失直接把本地bin目录下对应runtime的原生文件拷贝到部署目录根路径,或
- 调整GDAL初始化位置:不要把
GdalConfiguration.ConfigureGdal()、GdalConfiguration.ConfigureOgr()、Ogr.RegisterAll()放在接口方法内重复执行,把这几行代码移到Startup.Configure方法中,应用启动时仅初始化一次,避免并发请求下重复初始化GDAL导致锁冲突或加载异常。 - 若初始化后提示找不到GDAL投影表、数据文件,手动在初始化代码中添加配置指定数据路径:
Gdal.SetConfigOption("GDAL_DATA", Path.Combine(AppContext.BaseDirectory, "gdal-data"));
内容的提问来源于stack exchange,提问作者hamed
相关产品推荐
相关产品推荐

