内容目录
模型类:
public class Test
{
[JsonConverter(typeof(string))]
public int Value { get; set; }
}
API 接口:
[HttpPost("aaa")]
public string AAA([FromBody] Test test)
{
return "11111111111";
}
但是 Swagger 还是显示 int 类型,没有跟着 json 配置而变化。
所以我们需要配置 Swagger,显示转换类型之后正确的类型信息。
定义一个过滤器:
/// <summary>
/// Swagger 模型类过滤器
/// </summary>
public class MaomiSwaggerSchemaFilter : ISchemaFilter
{
/// <summary>
///
/// </summary>
/// <param name="schema">Swagger 中的属性</param>
/// <param name="context">模型类上下文</param>
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
// 模型类的类型
var type = context.Type;
// 如果 API 参数不是对象
if (type.IsPrimitive || TypeInfo.GetTypeCode(type) != TypeCode.Object)
{
return;
}
// 如果 API 参数是对象类型
// 获取类型的所有属性
PropertyInfo[] ps = context.Type.GetProperties();
// 获取 swagger 文件显示的所有属性
// 注意文档属性是已经已经生成的,这里进行后期转换,替换为需要显示的类型
foreach (var property in schema.Properties)
{
var p = ps.FirstOrDefault(x => x.Name.ToLower() == property.Key.ToLower());
if (p == null) continue;
var t = property.Value.Type;
var converter = p.GetCustomAttribute<JsonConverterAttribute>();
if (converter == null || converter.ConverterType == null) continue;
var targetType = TypeInfo.GetTypeCode(converter.ConverterType);
// 如果是基元类型或 Decimal、DateTime
if (targetType != TypeCode.Empty &&
targetType != TypeCode.DBNull &&
targetType != TypeCode.Object)
{
if (GetValueType(targetType, out var valueType))
{
property.Value.Type = valueType;
}
}
}
static bool GetValueType(TypeCode targetType, out string? valueType)
{
valueType = null;
switch (targetType)
{
case TypeCode.Boolean: valueType = "boolean"; break;
case TypeCode.Char: valueType = "string"; break;
case TypeCode.SByte: valueType = "integer"; break;
case TypeCode.Byte: valueType = "integer"; break;
case TypeCode.Int16: valueType = "integer"; break;
case TypeCode.UInt16: valueType = "integer"; break;
case TypeCode.Int32: valueType = "integer"; break;
case TypeCode.UInt32: valueType = "integer"; break;
case TypeCode.Int64: valueType = "integer"; break;
case TypeCode.UInt64: valueType = "integer"; break;
case TypeCode.Single: valueType = "number"; break;
case TypeCode.Double: valueType = "number"; break;
case TypeCode.Decimal: valueType = "number"; break;
case TypeCode.DateTime: valueType = "string"; break;
case TypeCode.String: valueType = "string"; break;
// 一般不需要处理对象
// case TypeCode.Object: valueType = p.PropertyType.Name; break;
default: return false;
}
return true;
}
}
}
一般不需要处理对象,如果有需要,可以使用:
case TypeCode.Object: property.Value.Type = p.PropertyType.Name;break;
然后配置 Swagger 服务。
builder.Services.AddSwaggerGen(options =>
{
options.SchemaFilter<CustomSchemaFilter>();
});
对应的基元类型在 Swagger 中显示的类型:
public class Test
{
public Boolean Value1 { get; set; }
public char Value2 { get; set; }
public sbyte Value3 { get; set; }
public byte Value4 { get; set; }
public Int16 Value5 { get; set; }
public UInt16 Value6 { get; set; }
public Int32 Value7 { get; set; }
public UInt32 Value8 { get; set; }
public Int64 Value9 { get; set; }
public UInt64 Value { get; set; }
public Single Value10 { get; set; }
public Double Value11 { get; set; }
public Decimal Value12 { get; set; }
public DateTime Value13 { get; set; }
public String Value14 { get; set; }
}
{
value1 boolean
value2 string
value3 integer($int32)
value4 integer($int32)
value5 integer($int32)
value6 integer($int32)
value7 integer($int32)
value8 integer($int32)
value9 integer($int64)
value integer($int64)
value10 number($float)
value11 number($double)
value12 number($double)
value13 string($date-time)
value14 string
}
文章评论