ASP.NET/ Swagger/ NetTopologySuite.Geometries 修正样例值
如之前的随笔提到的,NTS的图形类型对应的Swagger UI中的Example Value是图形类型的完整结构,这明显不是我们想要的。
我们期望在Example Value中显示可供使用的GeoJSON的样板,这样既直观,也更有利于调试。
点击查看代码
{ "name": "string", "geom": { "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": { "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinateSequence": { "ordinates": 0, "first": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "last": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinates": [ { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } ], "dimension": 0, "boundaryDimension": 0, "x": 0, "y": 0, "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "ogcGeometryType": 1, "boundary": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "z": 0, "m": 0 }, "interiorPoint": { "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinateSequence": { "ordinates": 0, "first": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "last": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinates": [ { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } ], "dimension": 0, "boundaryDimension": 0, "x": 0, "y": 0, "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "ogcGeometryType": 1, "boundary": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "z": 0, "m": 0 }, "pointOnSurface": { "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinateSequence": { "ordinates": 0, "first": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "last": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinates": [ { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } ], "dimension": 0, "boundaryDimension": 0, "x": 0, "y": 0, "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "ogcGeometryType": 1, "boundary": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "z": 0, "m": 0 }, "envelope": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinateSequence": { "ordinates": 0, "first": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "last": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "startPoint": { "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinateSequence": { "ordinates": 0, "first": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "last": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinates": [ { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } ], "dimension": 0, "boundaryDimension": 0, "x": 0, "y": 0, "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "ogcGeometryType": 1, "boundary": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "z": 0, "m": 0 }, "endPoint": { "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinateSequence": { "ordinates": 0, "first": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "last": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } }, "coordinates": [ { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } ], "dimension": 0, "boundaryDimension": 0, "x": 0, "y": 0, "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "ogcGeometryType": 1, "boundary": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } }, "z": 0, "m": 0 }, "ogcGeometryType": 1, "boundary": { "coordinate": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" }, "dimension": 0, "boundaryDimension": 0, "ogcGeometryType": 1, "boundary": "string", "factory": { "precisionModel": { "scale": 0, "precisionModelType": 0 }, "coordinateSequenceFactory": { "ordinates": 0 }, "srid": 0, "geometryServices": { "geometryOverlay": {}, "coordinateEqualityComparer": {}, "defaultCoordinateSequenceFactory": { "ordinates": 0 }, "defaultPrecisionModel": { "scale": 0, "precisionModelType": 0 } } }, "userData": "string", "srid": 0, "precisionModel": { "scale": 0, "precisionModelType": 0 }, "centroid": "string", "interiorPoint": "string", "pointOnSurface": "string", "envelope": "string", "envelopeInternal": { "centre": { "x": 0, "y": 0, "z": 0, "m": 0, "coordinateValue": "string" } } } } }
查了资料,发明可以通过给特殊类型添加Open API的Scheme来实现,首先找到了GeoJSON在Open API Scheme描述:
https://gist.github.com/codan-telcikt/e1d59ccc9a3af83e083f1a514c84026c
本来打算自己以此为模板用C#做一遍描述,还是因为懒,继续在Gayhub搜索:OpenApiSchema LineString
,只找到了五条记录,心理一凉,本来以为无了,没想到还真有轮子。
是一个还在beta版本的工具,目前来看也没有太活跃,不过他确实实现了GeoJSON的大部分到Open API Scheme的映射,源文件在:
直接想使用轮子的话可以直接
dotnet add package Rocket.Surgery.LaunchPad.AspNetCore.Spatial --version 0.1.0-beta.1
考虑到软件为测试版本,且应用的内容很少,于是我决定直接使用代码段:
点击查看代码
using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; using NetTopologySuite.Features; using NetTopologySuite.Geometries; using Swashbuckle.AspNetCore.SwaggerGen; namespace DEMO.Common; public class GeoJSONSchemes { class DocumentFilter : IDocumentFilter { public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { swaggerDoc.Components.Schemas.Add( "Point3D", new OpenApiSchema { Type = "array", Description = "Point in 3D space", ExternalDocs = new OpenApiExternalDocs { Url = new Uri("http://geojson.org/geojson-spec.html#id2") }, MinItems = 2, MaxItems = 3, Items = new OpenApiSchema { Type = "number" } } ); swaggerDoc.Components.Schemas.Add("Geometry", new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#geometry-objects"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(Geometry).FullName) }, Description = "GeoJSON geometry", Discriminator = new OpenApiDiscriminator { PropertyName = "type", }, Required = new HashSet<string> {"type"}, Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema { Type = "string", Enum = new List<IOpenApiAny> { new OpenApiString("Point"), new OpenApiString("LineString"), new OpenApiString("Polygon"), new OpenApiString("MultiPoint"), new OpenApiString("MultiLineString"), new OpenApiString("MultiPolygon"), }, Description = "the geometry type" } } } ); } } public static void ConfigureForNetTopologySuite(SwaggerGenOptions c) { c.DocumentFilter<DocumentFilter>(); c.MapType<Geometry>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#geometry-objects"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(Geometry).FullName) }, Description = "GeoJSON geometry", Discriminator = new OpenApiDiscriminator { PropertyName = "type", }, Required = new HashSet<string> {"type"}, Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema { Type = "string", Enum = new List<IOpenApiAny> { new OpenApiString("Point"), new OpenApiString("LineString"), new OpenApiString("Polygon"), new OpenApiString("MultiPoint"), new OpenApiString("MultiLineString"), new OpenApiString("MultiPolygon"), }, Description = "the geometry type" } } } ); c.MapType<Point>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#id2"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(Point).FullName) }, Description = "GeoJSON Point", AllOf = new List<OpenApiSchema> { new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Geometry", } }, new OpenApiSchema { Properties = new Dictionary<string, OpenApiSchema> { ["coordinates"] = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Point3D" } } } } }, } ); c.MapType<LineString>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#id3"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(LineString).FullName) }, Description = "GeoJSON LineString", AllOf = new List<OpenApiSchema> { new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Geometry", } }, new OpenApiSchema { Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema() { Type = "string", Enum = new List<IOpenApiAny> { new OpenApiString("LineString"), }, }, ["coordinates"] = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Point3D" } } } } } }, } ); c.MapType<Polygon>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#id4"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(Polygon).FullName) }, Description = "GeoJSON Polygon", AllOf = new List<OpenApiSchema> { new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Geometry", } }, new OpenApiSchema { Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema() { Type = "string", Enum = new List<IOpenApiAny> { new OpenApiString("Polygon"), }, }, ["coordinates"] = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Point3D" } } } } } } }, } ); c.MapType<MultiPoint>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#id4"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(MultiPoint).FullName) }, Description = "GeoJSON MultiPolygon", AllOf = new List<OpenApiSchema> { new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Geometry", } }, new OpenApiSchema { Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema() { Type = "string", Enum = new List<IOpenApiAny> { new OpenApiString("MultiPoint"), }, }, ["coordinates"] = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Point3D" } } } } } }, } ); c.MapType<MultiLineString>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#id5"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(MultiLineString).FullName) }, Description = "GeoJSON MultiLineString", AllOf = new List<OpenApiSchema> { new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Geometry", } }, new OpenApiSchema { Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema() { Type = "string", Enum = new List<IOpenApiAny> { new OpenApiString("MultiLineString"), }, }, ["coordinates"] = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Point3D" } } } } } } }, } ); c.MapType<MultiPolygon>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#id6"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(MultiPolygon).FullName) }, Description = "GeoJSON MultiPolygon", AllOf = new List<OpenApiSchema> { new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Geometry", } }, new OpenApiSchema { Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema() { Type = "string", Enum = new List<IOpenApiAny> { new OpenApiString("MultiPolygon"), }, }, ["coordinates"] = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Point3D" } } } } } } } }, } ); c.MapType<GeometryCollection>( () => new OpenApiSchema { ExternalDocs = new OpenApiExternalDocs { Url = new("http://geojson.org/geojson-spec.html#geometrycollection"), }, Type = "object", Extensions = new Dictionary<string, IOpenApiExtension> { ["clrType"] = new OpenApiString(typeof(GeometryCollection).FullName) }, Required = new HashSet<string> {"type", "geometries"}, Description = "GeoJSON geometry collection", Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema { Type = "string", Enum = new List<IOpenApiAny> {new OpenApiString("GeometryCollection")}, }, ["geometries"] = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Geometry" } } } } } ); c.MapType<Feature>( () => new OpenApiSchema { Type = "object", Description = "GeoJSON Feature", Required = new HashSet<string> {"type", "id", "geometry"}, ExternalDocs = new OpenApiExternalDocs { Url = new("https://tools.ietf.org/html/rfc7946#section-3.2") }, Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema { Type = "string", Enum = new List<IOpenApiAny> {new OpenApiString("Feature")} }, ["id"] = new OpenApiSchema { Type = "integer", }, ["geometry"] = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "GeometryCollection", } }, ["properties"] = new OpenApiSchema { Type = "object" } } } ); c.MapType<FeatureCollection>( () => new OpenApiSchema { Type = "object", Description = "GeoJSON Feature collection", Required = new HashSet<string> {"type", "features"}, ExternalDocs = new OpenApiExternalDocs { Url = new("https://tools.ietf.org/html/rfc7946#section-3.2") }, Properties = new Dictionary<string, OpenApiSchema> { ["type"] = new OpenApiSchema { Type = "string", Enum = new List<IOpenApiAny> {new OpenApiString("FeatureCollection")} }, ["features"] = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Feature" } } } } } ); } }
https://gist.github.com/yuhangch/90a63e4821ba6b2d6f1eee31b025cbf2
之后在Program.cs
中的AddSwaggerGen
方法中应用即可。
builder.Services.AddSwaggerGen(GeoJSONSchemes.ConfigureForNetTopologySuite);
这时Example Value就如我们期望的那样了:
{ "name": "string", "geom": { "type": "LineString", "coordinates": [ [ 0, 0 ] ] } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南