Swagger 之 自定义类型拦截
问题产生
本人从事gis行业,使用NetTopologySuite库时,api 暴露的 dto 中存在地理数据模型,直接转json会很长而且存在循环嵌套问题。server采用aspnetcore webapi ,配置controller时添加JsonSerializerOptions.Converters,以达到dto中的地理模型转换为简洁的数据交换格式(如 wkt)。但是swagger ui出现了问题。
本文目标 :Geometry类型及其子类 -> 在swagger ui中显示为 string
配置json Converters
说明
- SpatialDataConverter 实现了数据转换,这里不展示全部代码
public class WktJsonConverter<T> : JsonConverter<T> where T : Geometry
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return SpatialDataConverter.WktToGeometry<T>(reader.GetString());
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var wktJson = SpatialDataConverter.GeometryToWkt(value);
writer.WriteStringValue(wktJson);
}
}
//在Startu.cs文件 ConfigureServices 中配置
services.AddControllers().AddJsonOptions(option =>
{
var converters = option.JsonSerializerOptions.Converters;
converters.Add(new WktJsonConverter<Point>());
converters.Add(new WktJsonConverter<Polygon>());
converters.Add(new WktJsonConverter<LinearRing>());
converters.Add(new WktJsonConverter<LineString>());
converters.Add(new WktJsonConverter<MultiPolygon>());
converters.Add(new WktJsonConverter<Geometry>());
});
swagger ui 问题出现了 这个Polygon类型太长了,也不满足我们预期的wkt格式(string)

解决问题 - ISchemaFilter
//实现 ISchemaFilter
public class GeometrySchemaFilter : ISchemaFilter
{
private static readonly Dictionary<Type, SchemaChangeType> mapper = new()
{
//[类型]=显示
[typeof(Point)] = new SchemaChangeType("string", "POINT (1 2)"),
[typeof(Polygon)] = new SchemaChangeType("string", "POLYGON ((1 0,1 1, 0 0 , 1 0))"),
[typeof(LinearRing)] = new SchemaChangeType("string", "LINEARRING (1 0, 1 1, 0 0, 1 0)"),
[typeof(LineString)] = new SchemaChangeType("string", "LINESTRING (1 0, 1 1)"),
[typeof(MultiPolygon)] = new SchemaChangeType("string", "MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2)),((6 3,9 2,9 4,6 3)))"),
[typeof(Geometry)] = new SchemaChangeType("string", "POINT (1 2)"),
};
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (mapper.TryGetValue(context.Type, out var value))
{
schema.Properties.Clear();
schema.Type = value.Type;
schema.Example = new OpenApiString(value.Value);
}
}
}
internal class SchemaChangeType
{
public SchemaChangeType(string type, string value)
{
Type = type;
Value = value;
}
public string Type { get; set; }
public string Value { get; set; }
}
//AddSwaggerGen中配置
//重新定义example
c.SchemaFilter<GeometrySchemaFilter>();
效果


浙公网安备 33010602011771号