首页 > 其他分享 >.Net6 扩展Swagger

.Net6 扩展Swagger

时间:2023-10-26 15:45:24浏览次数:35  
标签:扩展 System new using var Net6 dt Swagger public

.Net6 扩展Swagger

net6集成了swagger的基础功能,但功能不够用

因此只能自定义扩展方法了,如下

1、集成Jwt授权

builder.Services.AddSwaggerGen();

改成

builder.Services.AddSwaggerGen(c =>
{ 
    var scheme = new OpenApiSecurityScheme()
    {
        Description = "Authorization header. \r\nExample: 'Bearer abcdefxxx'",
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Authorization"
        },
        Scheme = "oauth2",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,  
    };
    c.AddSecurityDefinition("Authorization", scheme);
    var requirement = new OpenApiSecurityRequirement();
    requirement[scheme] = new List<string>();
    c.AddSecurityRequirement(requirement); 
});

2、增加Swagger注释

增加swagger注释后,测试人员/前段开发人员就可以自己看文档了

2.1、设置Model层和Api层项目XML输出

代码如下:

img

builder.Services.AddSwaggerGen(c =>
{
    var basePath = Path.GetDirectoryName(AppContext.BaseDirectory);
    //c.IncludeXmlComments(Path.Combine(basePath, Assembly.GetExecutingAssembly().GetName().Name+".xml"), true);
    c.IncludeXmlComments(Path.Combine(basePath, "swap.xml"), true);
    c.IncludeXmlComments(Path.Combine(basePath, "swapModels.xml"), true);

    //
    var scheme = new OpenApiSecurityScheme()
    {
        Description = "Authorization header. \r\nExample: 'Bearer 12345abcdef'",
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Authorization"
        },
        Scheme = "oauth2",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,  
    };
    c.AddSecurityDefinition("Authorization", scheme);
    var requirement = new OpenApiSecurityRequirement();
    requirement[scheme] = new List<string>();
    c.AddSecurityRequirement(requirement); 
});

3、自定义属性隐藏及Api方法隐藏

3.1、Api层新建swagger过滤器

using Microsoft.OpenApi.Models;
using swapCommon;//HiddenFieldAttribute 和 HiddenAttribute 在公共类库存 
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text; 

namespace swapInit
{ 
    public class HiddenApiFilter : IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            foreach (var item in context.ApiDescriptions)
            {
                if (item.TryGetMethodInfo(out MethodInfo methodInfo))
                {
                    if (methodInfo.ReflectedType.CustomAttributes.Any(t => t.AttributeType == typeof(HiddenAttribute))
                    || methodInfo.CustomAttributes.Any(t => t.AttributeType == typeof(HiddenAttribute)))
                    {
                        var key = "/" + item.RelativePath.TrimEnd('/');
                        if (key.Contains("?"))
                        {
                            int idx = key.IndexOf("?", StringComparison.Ordinal);
                            key = key.Substring(0, idx);
                        }
                        if (swaggerDoc.Paths.ContainsKey(key))
                        {
                            swaggerDoc.Paths.Remove(key);
                        }
                    }
                }
            }
        }
    }


    public class HiddenFieldFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (schema?.Properties == null)
            {
                return;
            }
            var name = context.Type.FullName;
            var excludedProperties = context.Type.GetProperties();
            foreach (var property in excludedProperties)
            {
                var attribute = property.GetCustomAttribute<HiddenFieldAttribute>();
                if (attribute != null
                    && schema.Properties.ContainsKey(ToLowerStart(property.Name)))
                {
                    schema.Properties.Remove(ToLowerStart(property.Name));
                }
            };
        }
        public static string ToLowerStart( string source)
        {
            if (string.IsNullOrWhiteSpace(source))
            {
                return source;
            }
            var start = source.Substring(0, 1);
            return $"{start.ToLower()}{source.Substring(1, source.Length - 1)}";
        }
    } 
}

3.2、公共类库层新建属性类

using System;
using System.Collections.Generic;
using System.Text;

namespace swapCommon
{
    [AttributeUsage(AttributeTargets.Property)]
    public class HiddenFieldAttribute : Attribute
    {
    }

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
    public class HiddenAttribute : Attribute
    {
    }
}

3.3、引用上述过滤器

img

builder.Services.AddSwaggerGen(c =>
{
    var basePath = Path.GetDirectoryName(AppContext.BaseDirectory);
    //c.IncludeXmlComments(Path.Combine(basePath, Assembly.GetExecutingAssembly().GetName().Name+".xml"), true);
    c.IncludeXmlComments(Path.Combine(basePath, "swap.xml"), true);
    c.IncludeXmlComments(Path.Combine(basePath, "swapModels.xml"), true);
    //
    c.DocumentFilter<HiddenApiFilter>(); 
    c.SchemaFilter<HiddenFieldFilter>();
    //
    var scheme = new OpenApiSecurityScheme()
    {
        Description = "Authorization header. \r\nExample: 'Bearer 12345abcdef'",
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Authorization"
        },
        Scheme = "oauth2",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,  
    };
    c.AddSecurityDefinition("Authorization", scheme);
    var requirement = new OpenApiSecurityRequirement();
    requirement[scheme] = new List<string>();
    c.AddSecurityRequirement(requirement); 
});

3.4、测试Swagger过滤器

3.4.1、定义一个Post方法

        /// <summary>
        /// 演示字段隐藏
        /// </summary>
        /// <param name="stdto"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetStdto")] 
        public IActionResult GetStdto([FromBody]stdto stdto)
        {
            var dt = DateTime.Now;
            return Ok(dt );
        }

3.4.2、定义参数实体

有了身份证号,可以自动计算出年龄等场景

    public class stdto
    {
        public string name { get; set; }
        public string IdCard { get; set; }
        /// <summary>
        /// 该字段会在swagger中隐藏
        /// </summary>
        [HiddenField]
        public int age { get; set; }
    }

3.5、[Hidden]隐藏 Action 方法

不想让测试或前端在swagger上看到某方法,那就隐藏

        /// <summary>
        /// 演示Api隐藏 ,该方法不会展示在swagger上
        /// </summary>
        /// <param name="Hs">https://www.cnblogs.com/catcher1994/p/responsecaching.html</param>
        /// <returns></returns>
        [HttpGet]
        [Hidden]
        [Route("GetTime")] 
        public IActionResult GetTime()
        {
            var dt = DateTime.Now;
            return Ok(dt);
        }

4、规定项目时间返回格式

4.1、公共类库层先建JsonResult格式化类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json; 
using System.Text.Json.Serialization;

namespace swapCommon.Ext
{
    public class JsonOptionsExt : JsonConverter<DateTime>
    {
        private readonly string Format;
        public JsonOptionsExt(string format = "yyyy-MM-dd HH:mm:ss")
        {
            Format = format;
        }
        public override void Write(Utf8JsonWriter writer, DateTime date, JsonSerializerOptions options)
        {
            writer.WriteStringValue(date.ToString(Format));
        }
        public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            // 获取时间类型的字符串
            var dt = reader.GetString();
            if (!string.IsNullOrEmpty(dt))
            {
                //将日期与时间之间的"T"替换为一个空格,将结尾的"Z"去掉,否则会报错
                dt = dt.Replace("T", " ").Replace("Z", "");
                //取到秒,毫秒内容也要去掉,经过测试,不去掉会报错
                if (dt.Length > 19)
                {
                    dt = dt.Substring(0, 19);
                }
                return DateTime.ParseExact(dt, Format, null);
            }
            return DateTime.Now;
        }
    }
}

4.2、添加控制器时引用

builder.Services.AddControllers()

改成

builder.Services.AddControllers().AddJsonOptions(options =>
{
    //时间格式化响应
    options.JsonSerializerOptions.Converters.Add(new JsonOptionsExt());
}); 

改好后,时间的返回就统一了

img

4.3、补充

关于时间格式为 "yyyy-MM-dd HH:mm:ss" 也可以不使用自定义的JsonOptionsExt

添加Nutget引用,Microsoft.AspNetCore.Mvc.NewtonsoftJson V6.0.6

AddControllers()代码段替换为:

builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
    options.SerializerSettings.ContractResolver = new DefaultContractResolver();
}); 

其中

options.SerializerSettings.ContractResolver = new DefaultContractResolver(); /*支持接收JOBject动态参数*/

JOBject 动态参数,例如

        [AllowAnonymous]
        [HttpPost]
        [Route("TestAlter")]
        public IActionResult TestAlter([FromBody] JObject data)
        { 
            return Ok(data);
        } 

可接受任意json

标签:扩展,System,new,using,var,Net6,dt,Swagger,public
From: https://www.cnblogs.com/nuomibaibai/p/17789560.html

相关文章

  • 10月26日开启进程以及扩展点
    目录开启进程开启方式一开启方式二验证主进程和子进程直接是否具有内存隔离僵尸进程以及孤儿进程(了解)孤儿进程开启进程开启子进程的时候:把父进程的代码完整复制到一个新的内存空间里去执行,达到多个并行的作用开启方式一首先调用multiprocessing里面的Processfrommultipr......
  • 灵活、可用、高扩展,EasyMR 带来全新 Yarn 的队列管理功能及可视化配置
    YARN(YetAnotherResourceNegotiator)是Hadoop生态系统中的资源调度器,主要用于资源管理和作业调度。YARN自身具备队列管理功能,通过对YARN资源队列进行配置和管理,实现集群资源的分配,以满足不同应用和用户的需求。YARN的引入为集群在利用率、资源统一管理和数据共享等方面带来......
  • 扩展域并查集详解
    如有错漏之处,敬请各位奆佬指正!这是个比较冷门的数据结构。。。(其实很简单而且并不冷门)我是在做 P1892[BOI2003]团伙的时候听说的。那么,我就来讲解一下这个结构。updat2020-09-17准备开始扩写这篇文章一、预备知识并查集好像也没了...所以我说他很菜嘛...二、引......
  • php-pdo-mysql扩展
    #安装依赖包yuminstallm4yuminstallautoconf#进入对应版本的php安装包的ext/pdo_mysql目录,如下cd/usr/local/src/php-7.4.8/ext/pdo_mysql#在ext/pdo_mysql目录执行phpize/usr/local/php/bin/phpize#执行configure,其中:#--with-pdo-mysql为mysql的安装路径./config......
  • 随手笔记:Swagger 报错 NO Found /swagger/V1/swagger.json
    开发本地测试没问题,发布iis报错原因:swagger判断开发环境和发布环境解决办法:在startup.cs文件中找到调用swagger方法不做判断app.UseSwagger();      app.UseSwaggerUI(c=>c.SwaggerEndpoint("/swagger/v1/swagger.json","MyWebAPIV1"));如图所示:......
  • JS 对象的扩展
    属性的简洁表示法ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。constfoo='bar';constbaz={foo};baz//{foo:"bar"}//等同于constbaz={foo:foo};上面代码中,变量foo直接写在大括号里面。这时,属性名就是变量名,属性值就是变......
  • JS 数组的扩展
    扩展运算符含义扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。console.log(...[1,2,3])//123console.log(1,...[2,3,4],5)//12345[...document.querySelectorAll('div')]//[<div>,<div>,<div>]该运算符主要......
  • JS 函数的扩展
    函数参数的默认值基本用法ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。functionlog(x,y){y=y||'World';console.log(x,y);}log('Hello')//HelloWorldlog('Hello','China')//HelloChinalog('Hello','')//......
  • Laravel日志相关的扩展包
    在Laravel中,有几个常用的第三方扩展包可以帮助您记录系统日志和操作日志。以下是其中一些扩展包的例子:Monolog:Monolog是一个功能强大的日志记录库,Laravel默认使用它来记录日志。它支持多种日志处理器和格式,可以将日志记录到文件、数据库、邮件、Syslog等不同的目标。您可......
  • Laravel开源免费的第三方订阅扩展包
    在Laravel中添加订阅功能,您可以使用以下一些开源免费的第三方扩展包:LaravelCashier:LaravelCashier是Laravel官方提供的扩展包,用于处理订阅和付款相关的功能。它集成了多个支付网关(如Stripe、Braintree等),可以轻松地实现用户订阅、付款和取消订阅等操作。LaravelSub......