├── tools
├── clear.bat
├── nuget.exe
├── pack.bat
├── pack.Magicodes.SwaggerUI.bat
└── .vscode
│ └── launch.json
├── res
├── 1.png
├── 2.png
├── 3.png
└── wechat.jpg
├── src
├── TestHost3.1
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ ├── WeatherForecast.cs
│ ├── Controllers
│ │ ├── HomeController.cs
│ │ ├── ValuesController.cs
│ │ └── WeatherForecastController.cs
│ ├── TestHost3.1.csproj
│ ├── appsettings.json
│ ├── Program.cs
│ └── Properties
│ │ └── launchSettings.json
├── TestHost
│ ├── appsettings.Development.json
│ ├── Controllers
│ │ ├── HomeController.cs
│ │ └── ValuesController.cs
│ ├── TestHost.csproj
│ ├── appsettings.json
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ └── Startup.cs
├── ApiGroupTestHost
│ ├── appsettings.Development.json
│ ├── Controllers
│ │ ├── HomeController.cs
│ │ ├── App1Controller.cs
│ │ └── App2Controller.cs
│ ├── ApiGroupTestHost.csproj
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── appsettings.json
│ └── Startup.cs
├── Magicodes.SwaggerUI
│ ├── Models
│ │ ├── ContactInfo.cs
│ │ ├── HiddenApiConfigInfo.cs
│ │ ├── ApiConfigInfo.cs
│ │ ├── SwaggerConfigInfo.cs
│ │ └── SwaggerDocInfo.cs
│ ├── SwaggerOperationFilter.cs
│ ├── SwaggerEnumSchemaFilter.cs
│ ├── SwaggerOperationIdFilter.cs
│ ├── Magicodes.SwaggerUI.csproj
│ ├── SwaggerEnumParameterFilter.cs
│ ├── DictionaryExtensions.cs
│ └── Extentions.cs
└── Magicodes.SwaggerUI.sln
├── .gitattributes
├── .gitignore
└── README.md
/tools/clear.bat:
--------------------------------------------------------------------------------
1 | cd ./nupkgs/
2 | del *.nupkg /f /q /a
3 | cd ../
--------------------------------------------------------------------------------
/res/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xin-lai/Magicodes.SwaggerUI/HEAD/res/1.png
--------------------------------------------------------------------------------
/res/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xin-lai/Magicodes.SwaggerUI/HEAD/res/2.png
--------------------------------------------------------------------------------
/res/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xin-lai/Magicodes.SwaggerUI/HEAD/res/3.png
--------------------------------------------------------------------------------
/res/wechat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xin-lai/Magicodes.SwaggerUI/HEAD/res/wechat.jpg
--------------------------------------------------------------------------------
/tools/nuget.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xin-lai/Magicodes.SwaggerUI/HEAD/tools/nuget.exe
--------------------------------------------------------------------------------
/tools/pack.bat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xin-lai/Magicodes.SwaggerUI/HEAD/tools/pack.bat
--------------------------------------------------------------------------------
/src/TestHost3.1/Startup.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xin-lai/Magicodes.SwaggerUI/HEAD/src/TestHost3.1/Startup.cs
--------------------------------------------------------------------------------
/tools/pack.Magicodes.SwaggerUI.bat:
--------------------------------------------------------------------------------
1 | call ./clear.bat
2 | call ./pack.bat "Magicodes.SwaggerUI.*.nupkg" "../src/Magicodes.SwaggerUI/Magicodes.SwaggerUI.csproj"
3 | @pause
--------------------------------------------------------------------------------
/src/TestHost/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/TestHost3.1/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/TestHost3.1/WeatherForecast.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TestHost3._1
4 | {
5 | public class WeatherForecast
6 | {
7 | public DateTime Date { get; set; }
8 |
9 | public int TemperatureC { get; set; }
10 |
11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
12 |
13 | public string Summary { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/TestHost/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace TestHost.Controllers
8 | {
9 | public class HomeController: ControllerBase
10 | {
11 | public IActionResult Index()
12 | {
13 | return Redirect("/swagger");
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/TestHost3.1/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace TestHost3._1.Controllers
8 | {
9 | public class HomeController: ControllerBase
10 | {
11 | public IActionResult Index()
12 | {
13 | return Redirect("/swagger");
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace ApiGroupTestHost.Controllers
8 | {
9 | public class HomeController: ControllerBase
10 | {
11 | public IActionResult Index()
12 | {
13 | return Redirect("/swagger");
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/TestHost3.1/TestHost3.1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | TestHost3._1
6 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/TestHost/TestHost.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.2
5 | InProcess
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/TestHost/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "SwaggerDoc": {
8 | "IsEnabled": "true",
9 | //将枚举值以字符串显示
10 | "DescribeAllEnumsAsStrings": false,
11 | "SwaggerDocInfos": [
12 | {
13 | "IsEnabled": "true",
14 | "Title": "APP API文档",
15 | "Version": "v1",
16 | //"GroupName": "",
17 | "Description": "",
18 | "Contact": {
19 | "Name": "心莱科技",
20 | "Email": "xinlai@xin-lai.com"
21 | },
22 | //"GroupUrlPrefix": "api/app1/"
23 | }
24 | ],
25 | "UseFullNameForSchemaId": "false"
26 | },
27 | "AllowedHosts": "*"
28 | }
29 |
--------------------------------------------------------------------------------
/src/TestHost3.1/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "SwaggerDoc": {
8 | "IsEnabled": "true",
9 | //将枚举值以字符串显示
10 | "DescribeAllEnumsAsStrings": false,
11 | "SwaggerDocInfos": [
12 | {
13 | "IsEnabled": "true",
14 | "Title": "APP API文档",
15 | "Version": "v1",
16 | //"GroupName": "",
17 | "Description": "",
18 | "Contact": {
19 | "Name": "心莱科技",
20 | "Email": "xinlai@xin-lai.com"
21 | }
22 | //"GroupUrlPrefix": "api/app1/"
23 | }
24 | ],
25 | "UseFullNameForSchemaId": "false"
26 | },
27 | "AllowedHosts": "*"
28 | }
29 |
--------------------------------------------------------------------------------
/src/TestHost/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Logging;
10 |
11 | namespace TestHost
12 | {
13 | public class Program
14 | {
15 | public static void Main(string[] args)
16 | {
17 | CreateWebHostBuilder(args).Build().Run();
18 | }
19 |
20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
21 | WebHost.CreateDefaultBuilder(args)
22 | .UseStartup();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/ApiGroupTestHost.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.2
5 | InProcess
6 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Logging;
10 |
11 | namespace ApiGroupTestHost
12 | {
13 | public class Program
14 | {
15 | public static void Main(string[] args)
16 | {
17 | CreateWebHostBuilder(args).Build().Run();
18 | }
19 |
20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
21 | WebHost.CreateDefaultBuilder(args)
22 | .UseStartup();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/TestHost3.1/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Hosting;
6 | using Microsoft.Extensions.Configuration;
7 | using Microsoft.Extensions.Hosting;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace TestHost3._1
11 | {
12 | public class Program
13 | {
14 | public static void Main(string[] args)
15 | {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/Models/ContactInfo.cs:
--------------------------------------------------------------------------------
1 | // ======================================================================
2 | //
3 | // Copyright (C) 2019-2030 湖南心莱信息科技有限公司
4 | // All rights reserved
5 | //
6 | // filename : ContactInfo.cs
7 | // description :
8 | //
9 | // created by 雪雁 at --
10 | // 文档官网:https://docs.xin-lai.com
11 | // 公众号教程:麦扣聊技术
12 | // QQ群:85318032(编程交流)
13 | // Blog:http://www.cnblogs.com/codelove/
14 | //
15 | // ======================================================================
16 |
17 | namespace Magicodes.SwaggerUI.Models
18 | {
19 | ///
20 | /// 联系信息
21 | ///
22 | public class ContactInfo
23 | {
24 | public string Name { get; set; }
25 | public string Email { get; set; }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/TestHost/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:13976",
8 | "sslPort": 0
9 | }
10 | },
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchBrowser": true,
15 | "launchUrl": "",
16 | "environmentVariables": {
17 | "ASPNETCORE_ENVIRONMENT": "Development"
18 | }
19 | },
20 | "TestHost": {
21 | "commandName": "Project",
22 | "launchBrowser": true,
23 | "launchUrl": "",
24 | "applicationUrl": "http://localhost:5000",
25 | "environmentVariables": {
26 | "ASPNETCORE_ENVIRONMENT": "Development"
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:31901",
8 | "sslPort": 0
9 | }
10 | },
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchBrowser": true,
15 | "launchUrl": "",
16 | "environmentVariables": {
17 | "ASPNETCORE_ENVIRONMENT": "Development"
18 | }
19 | },
20 | "ApiGroupTestHost": {
21 | "commandName": "Project",
22 | "launchBrowser": true,
23 | "launchUrl": "",
24 | "applicationUrl": "http://localhost:5000",
25 | "environmentVariables": {
26 | "ASPNETCORE_ENVIRONMENT": "Development"
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/TestHost3.1/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:43828",
8 | "sslPort": 0
9 | }
10 | },
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchBrowser": true,
15 | "launchUrl": "swagger/",
16 | "environmentVariables": {
17 | "ASPNETCORE_ENVIRONMENT": "Development"
18 | }
19 | },
20 | "TestHost3._1": {
21 | "commandName": "Project",
22 | "launchBrowser": true,
23 | "launchUrl": "swagger/",
24 | "applicationUrl": "http://localhost:5000",
25 | "environmentVariables": {
26 | "ASPNETCORE_ENVIRONMENT": "Development"
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/Models/HiddenApiConfigInfo.cs:
--------------------------------------------------------------------------------
1 | // ======================================================================
2 | //
3 | // Copyright (C) 2019-2030 湖南心莱信息科技有限公司
4 | // All rights reserved
5 | //
6 | // filename : HiddenApiConfig.cs
7 | // description :
8 | //
9 | // created by 雪雁 at --
10 | // 文档官网:https://docs.xin-lai.com
11 | // 公众号教程:麦扣聊技术
12 | // QQ群:85318032(编程交流)
13 | // Blog:http://www.cnblogs.com/codelove/
14 | //
15 | // ======================================================================
16 |
17 | using System.Collections.Generic;
18 |
19 | namespace Magicodes.SwaggerUI.Models
20 | {
21 | ///
22 | /// API隐藏配置
23 | ///
24 | public class HiddenApiConfigInfo
25 | {
26 | public bool IsEnabled { get; set; }
27 |
28 | ///
29 | ///
30 | ///
31 | public List Urls { get; set; }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/Models/ApiConfigInfo.cs:
--------------------------------------------------------------------------------
1 | // ======================================================================
2 | //
3 | // Copyright (C) 2019-2030 湖南心莱信息科技有限公司
4 | // All rights reserved
5 | //
6 | // filename : HiddenApiConfig.cs
7 | // description :
8 | //
9 | // created by 雪雁 at --
10 | // 文档官网:https://docs.xin-lai.com
11 | // 公众号教程:麦扣聊技术
12 | // QQ群:85318032(编程交流)
13 | // Blog:http://www.cnblogs.com/codelove/
14 | //
15 | // ======================================================================
16 |
17 | namespace Magicodes.SwaggerUI.Models
18 | {
19 | ///
20 | /// API配置
21 | ///
22 | public class ApiConfigInfo
23 | {
24 | ///
25 | /// 支持部分路径匹配
26 | ///
27 | public string Url { get; set; }
28 |
29 | ///
30 | /// HTTP方法配置(Get、Post),默认“*”
31 | ///
32 | public string HttpMethod { get; set; } = "*";
33 | }
34 | }
--------------------------------------------------------------------------------
/src/TestHost/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace TestHost.Controllers
8 | {
9 | [Route("api/[controller]")]
10 | [ApiController]
11 | public class ValuesController : ControllerBase
12 | {
13 | // GET api/values
14 | [HttpGet]
15 | public ActionResult> Get()
16 | {
17 | return new string[] { "value1", "value2" };
18 | }
19 |
20 | // GET api/values/5
21 | [HttpGet("{id}")]
22 | public ActionResult Get(int id)
23 | {
24 | return "value";
25 | }
26 |
27 | // POST api/values
28 | [HttpPost]
29 | public void Post([FromBody] string value)
30 | {
31 | }
32 |
33 | // PUT api/values/5
34 | [HttpPut("{id}")]
35 | public void Put(int id, [FromBody] string value)
36 | {
37 | }
38 |
39 | // DELETE api/values/5
40 | [HttpDelete("{id}")]
41 | public void Delete(int id)
42 | {
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/TestHost3.1/Controllers/ValuesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace TestHost3._1.Controllers
8 | {
9 | [Route("api/[controller]")]
10 | [ApiController]
11 | public class ValuesController : ControllerBase
12 | {
13 | // GET api/values
14 | [HttpGet]
15 | public ActionResult> Get()
16 | {
17 | return new string[] { "value1", "value2" };
18 | }
19 |
20 | ///
21 | /// 获取
22 | ///
23 | ///
24 | ///
25 | [HttpGet("{id}")]
26 | public ActionResult Get(int id)
27 | {
28 | return "value";
29 | }
30 |
31 | // POST api/values
32 | [HttpPost]
33 | public void Post([FromBody] string value)
34 | {
35 | }
36 |
37 | // PUT api/values/5
38 | [HttpPut("{id}")]
39 | public void Put(int id, [FromBody] string value)
40 | {
41 | }
42 |
43 | // DELETE api/values/5
44 | [HttpDelete("{id}")]
45 | public void Delete(int id)
46 | {
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/Controllers/App1Controller.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace ApiGroupTestHost.Controllers
8 | {
9 | ///
10 | /// 测试
11 | ///
12 | [Route("api/app1/Values")]
13 | [ApiController]
14 | public class App1Controller : ControllerBase
15 | {
16 | ///
17 | /// 测试
18 | ///
19 | ///
20 | [HttpGet]
21 | public ActionResult> Get()
22 | {
23 | return new string[] { "value1", "value2" };
24 | }
25 |
26 | // GET api/values/5
27 | [HttpGet("{id}")]
28 | public ActionResult Get(int id)
29 | {
30 | return "value";
31 | }
32 |
33 | // POST api/values
34 | [HttpPost]
35 | public void Post([FromBody] string value)
36 | {
37 | }
38 |
39 | // PUT api/values/5
40 | [HttpPut("{id}")]
41 | public void Put(int id, [FromBody] string value)
42 | {
43 | }
44 |
45 | // DELETE api/values/5
46 | [HttpDelete("{id}")]
47 | public void Delete(int id)
48 | {
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/Controllers/App2Controller.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace ApiGroupTestHost.Controllers
8 | {
9 | ///
10 | /// 测试
11 | ///
12 | [Route("api/app2/Values")]
13 | [ApiController]
14 | public class App2Controller : ControllerBase
15 | {
16 | ///
17 | /// 测试
18 | ///
19 | ///
20 | [HttpGet]
21 | public ActionResult> Get()
22 | {
23 | return new string[] { "value1", "value2" };
24 | }
25 |
26 | // GET api/values/5
27 | [HttpGet("{id}")]
28 | public ActionResult Get(int id)
29 | {
30 | return "value";
31 | }
32 |
33 | // POST api/values
34 | [HttpPost]
35 | public void Post([FromBody] string value)
36 | {
37 | }
38 |
39 | // PUT api/values/5
40 | [HttpPut("{id}")]
41 | public void Put(int id, [FromBody] string value)
42 | {
43 | }
44 |
45 | // DELETE api/values/5
46 | [HttpDelete("{id}")]
47 | public void Delete(int id)
48 | {
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/TestHost3.1/Controllers/WeatherForecastController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Microsoft.Extensions.Logging;
7 |
8 | namespace TestHost3._1.Controllers
9 | {
10 | [ApiController]
11 | [Route("[controller]")]
12 | public class WeatherForecastController : ControllerBase
13 | {
14 | private static readonly string[] Summaries = new[]
15 | {
16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
17 | };
18 |
19 | private readonly ILogger _logger;
20 |
21 | public WeatherForecastController(ILogger logger)
22 | {
23 | _logger = logger;
24 | }
25 |
26 | [HttpGet]
27 | public IEnumerable Get()
28 | {
29 | var rng = new Random();
30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast
31 | {
32 | Date = DateTime.Now.AddDays(index),
33 | TemperatureC = rng.Next(-20, 55),
34 | Summary = Summaries[rng.Next(Summaries.Length)]
35 | })
36 | .ToArray();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/SwaggerOperationFilter.cs:
--------------------------------------------------------------------------------
1 | #if NETCOREAPP3_1
2 | using Swashbuckle.AspNetCore.SwaggerGen;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using Microsoft.OpenApi.Models;
8 |
9 | namespace Magicodes.SwaggerUI
10 | {
11 |
12 | public class SwaggerOperationFilter : IOperationFilter
13 | {
14 | public void Apply(OpenApiOperation operation, OperationFilterContext context)
15 | {
16 | if (operation.Parameters == null)
17 | {
18 | return;
19 | }
20 |
21 | for (var i = 0; i < operation.Parameters.Count; ++i)
22 | {
23 | var parameter = operation.Parameters[i];
24 |
25 | var enumType = context.ApiDescription.ParameterDescriptions[i].ParameterDescriptor.ParameterType;
26 | if (!enumType.IsEnum)
27 | {
28 | continue;
29 | }
30 |
31 | var schema = context.SchemaRepository.Schemas.GetOrAdd($"#/definitions/{enumType.Name}", () =>
32 | context.SchemaGenerator.GenerateSchema(enumType, context.SchemaRepository)
33 | );
34 |
35 | parameter.Schema = schema;
36 | }
37 | }
38 | }
39 |
40 | }
41 | #endif
42 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/SwaggerEnumSchemaFilter.cs:
--------------------------------------------------------------------------------
1 | #if NETCOREAPP3_1
2 | using System;
3 | using System.Linq;
4 | using Microsoft.OpenApi.Any;
5 | using Microsoft.OpenApi.Models;
6 | using Swashbuckle.AspNetCore.Swagger;
7 | using Swashbuckle.AspNetCore.SwaggerGen;
8 |
9 | namespace Magicodes.SwaggerUI
10 | {
11 |
12 | public class SwaggerEnumSchemaFilter : ISchemaFilter
13 | {
14 | public void Apply(OpenApiSchema schema, SchemaFilterContext context)
15 | {
16 | if (context.Type == null)
17 | {
18 | return;
19 | }
20 |
21 | var type = Nullable.GetUnderlyingType(context.Type) ?? context.Type;
22 | if (!type.IsEnum || schema.Extensions.ContainsKey("x-enumNames"))
23 | {
24 | return;
25 | }
26 |
27 | var enumNames = new OpenApiArray();
28 | enumNames.AddRange(Enum.GetNames(type).Select(_ => new OpenApiString(_)));
29 | schema.Extensions.Add("x-enumNames", enumNames);
30 | schema.Extensions.Add(
31 | "x-ms-enum",
32 | new OpenApiObject
33 | {
34 | ["name"] = new OpenApiString(type.Name),
35 | ["modelAsString"] = new OpenApiBoolean(true)
36 | }
37 | );
38 | }
39 | }
40 | }
41 | #endif
42 |
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "SwaggerDoc": {
8 | "IsEnabled": "true",
9 | //将枚举值以字符串显示
10 | "DescribeAllEnumsAsStrings": false,
11 | "SwaggerDocInfos": [
12 | {
13 | "IsEnabled": "true",
14 | "Title": "APP1 API文档",
15 | "Version": "v1",
16 | "GroupName": "App1",
17 | "Description": "",
18 | "Contact": {
19 | "Name": "心莱科技Team1",
20 | "Email": "xinlai@xin-lai.com"
21 | },
22 | "GroupUrlPrefix": "api/app1/"
23 | },
24 | {
25 | "IsEnabled": "true",
26 | "Title": "APP2 API文档",
27 | "Version": "v2",
28 | "GroupName": "App2",
29 | "Description": "",
30 | "Contact": {
31 | "Name": "心莱科技Team2",
32 | "Email": "xinlai@xin-lai.com"
33 | },
34 | "GroupUrlPrefix": "api/app2/",
35 | "HiddenApi": {
36 | "IsEnabled": "true",
37 | "Urls": [
38 | {
39 | "Url": "app2/Values/{id}",
40 | "HttpMethod": "Delete"
41 | }
42 | ]
43 | }
44 | }
45 | ],
46 | "HiddenApi": {
47 | "IsEnabled": "true",
48 | "Urls": [
49 | { "Url": "app1/Values/{id}" }
50 | ]
51 | },
52 | "UseFullNameForSchemaId": "false"
53 | },
54 | "AllowedHosts": "*"
55 | }
56 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/Models/SwaggerConfigInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Magicodes.SwaggerUI.Models
6 | {
7 | ///
8 | /// Swagger配置信息
9 | ///
10 | public class SwaggerConfigInfo
11 | {
12 | ///
13 | /// 是否启用
14 | ///
15 | public bool IsEnabled { get; set; }
16 |
17 |
18 | ///
19 | /// 将枚举值以字符串显示
20 | ///
21 | public bool DescribeAllEnumsAsStrings { get; set; }
22 |
23 | ///
24 | /// Api文档列表
25 | ///
26 | public List SwaggerDocInfos { get; set; }
27 |
28 | ///
29 | /// 在界面上显示验证(Authorize)按钮,验证按钮处理逻辑基于 wwwroot/swagger/ui/index.html
30 | ///
31 | public bool Authorize { get; set; }
32 |
33 | ///
34 | /// 隐藏API配置
35 | ///
36 | public HiddenApiConfigInfo HiddenApi { get; set; }
37 |
38 | ///
39 | /// 是否启用API全名
40 | ///
41 | public bool UseFullNameForSchemaId { get; set; }
42 |
43 | ///
44 | /// 需要从嵌入资源中加载的程序集全称
45 | ///
46 | public string ManifestResourceAssembly { get; set; }
47 |
48 | ///
49 | /// 嵌入资源路径
50 | ///
51 | public string ManifestResourceUrl { get; set; }
52 |
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/SwaggerOperationIdFilter.cs:
--------------------------------------------------------------------------------
1 | #if NETCOREAPP3_1
2 | using Microsoft.AspNetCore.Mvc.ApiExplorer;
3 | using Microsoft.OpenApi.Models;
4 | using Swashbuckle.AspNetCore.SwaggerGen;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Globalization;
8 | using System.Linq;
9 | using System.Text;
10 |
11 | namespace Magicodes.SwaggerUI
12 | {
13 |
14 | public class SwaggerOperationIdFilter : IOperationFilter
15 | {
16 | public void Apply(OpenApiOperation operation, OperationFilterContext context)
17 | {
18 | operation.OperationId = FriendlyId(context.ApiDescription);
19 | }
20 |
21 | private static string FriendlyId(ApiDescription apiDescription)
22 | {
23 | var parts = (RelativePathSansQueryString(apiDescription) + "/" + apiDescription.HttpMethod.ToLower())
24 | .Split('/');
25 |
26 | var builder = new StringBuilder();
27 | foreach (var part in parts)
28 | {
29 | var trimmed = part.Trim('{', '}');
30 | builder.AppendFormat("{0}{1}",
31 | (part.StartsWith("{") ? "By" : string.Empty),
32 | CultureInfo.InvariantCulture.TextInfo.ToTitleCase(trimmed)
33 | );
34 | }
35 |
36 | return builder.ToString();
37 | }
38 |
39 | private static string RelativePathSansQueryString(ApiDescription apiDescription)
40 | {
41 | return apiDescription.RelativePath.Split('?').First();
42 | }
43 | }
44 |
45 | }
46 | #endif
47 |
--------------------------------------------------------------------------------
/tools/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // 使用 IntelliSense 了解相关属性。
3 | // 悬停以查看现有属性的描述。
4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "PowerShell",
9 | "request": "launch",
10 | "name": "PowerShell Launch Current File",
11 | "script": "${file}",
12 | "args": [],
13 | "cwd": "${file}"
14 | },
15 | {
16 | "type": "PowerShell",
17 | "request": "launch",
18 | "name": "PowerShell Launch Current File in Temporary Console",
19 | "script": "${file}",
20 | "args": [],
21 | "cwd": "${file}",
22 | "createTemporaryIntegratedConsole": true
23 | },
24 | {
25 | "type": "PowerShell",
26 | "request": "launch",
27 | "name": "PowerShell Launch Current File w/Args Prompt",
28 | "script": "${file}",
29 | "args": [
30 | "${command:SpecifyScriptArgs}"
31 | ],
32 | "cwd": "${file}"
33 | },
34 | {
35 | "type": "PowerShell",
36 | "request": "attach",
37 | "name": "PowerShell Attach to Host Process",
38 | "processId": "${command:PickPSHostProcess}",
39 | "runspaceId": 1
40 | },
41 | {
42 | "type": "PowerShell",
43 | "request": "launch",
44 | "name": "PowerShell Interactive Session",
45 | "cwd": "${workspaceRoot}"
46 | }
47 | ]
48 | }
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/Magicodes.SwaggerUI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1;netcoreapp2.2;netstandard2.0
5 | SwaggerUI扩展
6 | 3.0.3
7 | True
8 | 湖南心莱信息科技有限公司
9 | http://www.cnblogs.com/codelove/
10 | 雪雁
11 |
12 | Magicodes SwaggerUI扩展库。
13 | 官方网址:https://xin-lai.com
14 | 订阅号:麦扣聊技术
15 | 开源库地址:https://github.com/xin-lai
16 | 博客地址:http://www.cnblogs.com/codelove/
17 | 交流QQ群:85318032
18 |
19 | https://github.com/xin-lai/Magicodes.SwaggerUI
20 | false
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/TestHost/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Magicodes.SwaggerUI;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.AspNetCore.Mvc;
9 | using Microsoft.Extensions.Configuration;
10 | using Microsoft.Extensions.DependencyInjection;
11 | using Microsoft.Extensions.Logging;
12 | using Microsoft.Extensions.Options;
13 |
14 | namespace TestHost
15 | {
16 | public class Startup
17 | {
18 | public Startup(IConfiguration configuration)
19 | {
20 | Configuration = configuration;
21 | }
22 |
23 | public IConfiguration Configuration { get; }
24 |
25 | // This method gets called by the runtime. Use this method to add services to the container.
26 | public void ConfigureServices(IServiceCollection services)
27 | {
28 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
29 | //添加自定义API文档生成(支持文档配置)
30 | services.AddMagicodesSwaggerGen(Configuration);
31 | }
32 |
33 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
34 | public void Configure(IApplicationBuilder app, IHostingEnvironment env)
35 | {
36 | if (env.IsDevelopment())
37 | {
38 | app.UseDeveloperExceptionPage();
39 | }
40 |
41 | app.UseMvc(routes => routes.MapRoute(
42 | "default",
43 | "{controller=Home}/{action=Index}/{id?}"));
44 |
45 | //启用自定义API文档(支持文档配置)
46 | app.UseMagicodesSwaggerUI(Configuration);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/ApiGroupTestHost/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Magicodes.SwaggerUI;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.AspNetCore.Mvc;
9 | using Microsoft.Extensions.Configuration;
10 | using Microsoft.Extensions.DependencyInjection;
11 | using Microsoft.Extensions.Logging;
12 | using Microsoft.Extensions.Options;
13 |
14 | namespace ApiGroupTestHost
15 | {
16 | public class Startup
17 | {
18 | public Startup(IConfiguration configuration)
19 | {
20 | Configuration = configuration;
21 | }
22 |
23 | public IConfiguration Configuration { get; }
24 |
25 | // This method gets called by the runtime. Use this method to add services to the container.
26 | public void ConfigureServices(IServiceCollection services)
27 | {
28 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
29 |
30 | //添加自定义API文档生成(支持文档配置)
31 | services.AddMagicodesSwaggerGen(Configuration);
32 | }
33 |
34 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
35 | public void Configure(IApplicationBuilder app, IHostingEnvironment env)
36 | {
37 | if (env.IsDevelopment())
38 | {
39 | app.UseDeveloperExceptionPage();
40 | }
41 |
42 | app.UseMvc(routes => routes.MapRoute(
43 | "default",
44 | "{controller=Home}/{action=Index}/{id?}"));
45 |
46 | //启用自定义API文档(支持文档配置)
47 | app.UseMagicodesSwaggerUI(Configuration);
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/Models/SwaggerDocInfo.cs:
--------------------------------------------------------------------------------
1 | // ======================================================================
2 | //
3 | // Copyright (C) 2019-2030 湖南心莱信息科技有限公司
4 | // All rights reserved
5 | //
6 | // filename : SwaggerDocInfo.cs
7 | // description :
8 | //
9 | // created by 雪雁 at --
10 | // 文档官网:https://docs.xin-lai.com
11 | // 公众号教程:麦扣聊技术
12 | // QQ群:85318032(编程交流)
13 | // Blog:http://www.cnblogs.com/codelove/
14 | //
15 | // ======================================================================
16 |
17 | namespace Magicodes.SwaggerUI.Models
18 | {
19 | ///
20 | /// API文档信息
21 | ///
22 | public class SwaggerDocInfo
23 | {
24 | ///
25 | /// 是否启用
26 | ///
27 | public bool IsEnabled { get; set; }
28 |
29 | ///
30 | /// 文档标题
31 | ///
32 | public string Title { get; set; }
33 |
34 | ///
35 | /// 分组名称
36 | ///
37 | public string GroupName { get; set; } = "v1";
38 |
39 | ///
40 | /// 版本
41 | ///
42 | public string Version { get; set; } = "v1";
43 |
44 | ///
45 | /// 描述
46 | ///
47 | public string Description { get; set; }
48 |
49 | ///
50 | /// 联系信息
51 | ///
52 | public ContactInfo Contact { get; set; }
53 |
54 | ///
55 | /// 分组Url前缀
56 | ///
57 | public string GroupUrlPrefix { get; set; }
58 |
59 | ///
60 | /// 隐藏API配置
61 | ///
62 | public HiddenApiConfigInfo HiddenApi { get; set; }
63 | }
64 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/SwaggerEnumParameterFilter.cs:
--------------------------------------------------------------------------------
1 | #if NETCOREAPP3_1
2 | using Microsoft.OpenApi.Any;
3 | using Microsoft.OpenApi.Models;
4 | using Swashbuckle.AspNetCore.SwaggerGen;
5 | using System;
6 | using System.Collections;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 |
11 | namespace Magicodes.SwaggerUI
12 | {
13 | public class SwaggerEnumParameterFilter : IParameterFilter
14 | {
15 | public void Apply(OpenApiParameter parameter, ParameterFilterContext context)
16 | {
17 | if (context.ApiParameterDescription.Type == null)
18 | {
19 | return;
20 | }
21 |
22 | var type = Nullable.GetUnderlyingType(context.ApiParameterDescription.Type) ?? context.ApiParameterDescription.Type;
23 | if (type.IsEnum)
24 | {
25 | AddEnumParamSpec(parameter, type, context);
26 | parameter.Required = type == context.ApiParameterDescription.Type;
27 | }
28 | else if (type.IsArray || (type.IsGenericType && type.GetInterfaces().Contains(typeof(IEnumerable))))
29 | {
30 | var itemType = type.GetElementType() ?? type.GenericTypeArguments.First();
31 | AddEnumSpec(parameter, itemType, context);
32 | }
33 | }
34 |
35 | private static void AddEnumSpec(OpenApiParameter parameter, Type type, ParameterFilterContext context)
36 | {
37 | var schema = context.SchemaRepository.Schemas.GetOrAdd($"#/definitions/{type.Name}", () =>
38 | context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository)
39 | );
40 |
41 | if (schema.Reference == null || !type.IsEnum)
42 | {
43 | return;
44 | }
45 |
46 | parameter.Schema = schema;
47 |
48 | var enumNames = new OpenApiArray();
49 | enumNames.AddRange(Enum.GetNames(type).Select(_ => new OpenApiString(_)));
50 | schema.Extensions.Add("x-enumNames", enumNames);
51 | }
52 |
53 | private static void AddEnumParamSpec(OpenApiParameter parameter, Type type, ParameterFilterContext context)
54 | {
55 | var schema = context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository);
56 | if (schema.Reference == null)
57 | {
58 | return;
59 | }
60 |
61 | parameter.Schema = schema;
62 |
63 | var enumNames = new OpenApiArray();
64 | enumNames.AddRange(Enum.GetNames(type).Select(_ => new OpenApiString(_)));
65 | schema.Extensions.Add("x-enumNames", enumNames);
66 | }
67 |
68 |
69 | }
70 | }
71 | #endif
72 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29123.88
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Magicodes.SwaggerUI", "Magicodes.SwaggerUI\Magicodes.SwaggerUI.csproj", "{6DFD6EA6-C394-45F0-932C-3661BA144451}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{99C60890-9805-4D50-B661-3AEEA7784EC2}"
9 | ProjectSection(SolutionItems) = preProject
10 | ..\README.md = ..\README.md
11 | EndProjectSection
12 | EndProject
13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiGroupTestHost", "ApiGroupTestHost\ApiGroupTestHost.csproj", "{736CFBFB-0DE8-4238-B82F-766D7E46BE83}"
14 | EndProject
15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestHost", "TestHost\TestHost.csproj", "{342ABF70-18A5-4CAB-B948-DCB647341BF7}"
16 | EndProject
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestHost3.1", "TestHost3.1\TestHost3.1.csproj", "{167AF511-4539-488C-9415-80FA2B3AE35F}"
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {6DFD6EA6-C394-45F0-932C-3661BA144451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {6DFD6EA6-C394-45F0-932C-3661BA144451}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {6DFD6EA6-C394-45F0-932C-3661BA144451}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {6DFD6EA6-C394-45F0-932C-3661BA144451}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {736CFBFB-0DE8-4238-B82F-766D7E46BE83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {736CFBFB-0DE8-4238-B82F-766D7E46BE83}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {736CFBFB-0DE8-4238-B82F-766D7E46BE83}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {736CFBFB-0DE8-4238-B82F-766D7E46BE83}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {342ABF70-18A5-4CAB-B948-DCB647341BF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {342ABF70-18A5-4CAB-B948-DCB647341BF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {342ABF70-18A5-4CAB-B948-DCB647341BF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {342ABF70-18A5-4CAB-B948-DCB647341BF7}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {167AF511-4539-488C-9415-80FA2B3AE35F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {167AF511-4539-488C-9415-80FA2B3AE35F}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {167AF511-4539-488C-9415-80FA2B3AE35F}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 | {167AF511-4539-488C-9415-80FA2B3AE35F}.Release|Any CPU.Build.0 = Release|Any CPU
41 | EndGlobalSection
42 | GlobalSection(SolutionProperties) = preSolution
43 | HideSolutionNode = FALSE
44 | EndGlobalSection
45 | GlobalSection(ExtensibilityGlobals) = postSolution
46 | SolutionGuid = {D15EDCA6-5121-4BD0-9C5F-62D46F58EF01}
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/DictionaryExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Magicodes.SwaggerUI
6 | {
7 | ///
8 | /// Extension methods for Dictionary.
9 | ///
10 | public static class DictionaryExtensions
11 | {
12 | ///
13 | /// This method is used to try to get a value in a dictionary if it does exists.
14 | ///
15 | /// Type of the value
16 | /// The collection object
17 | /// Key
18 | /// Value of the key (or default value if key not exists)
19 | /// True if key does exists in the dictionary
20 | internal static bool TryGetValue(this IDictionary dictionary, string key, out T value)
21 | {
22 | object valueObj;
23 | if (dictionary.TryGetValue(key, out valueObj) && valueObj is T)
24 | {
25 | value = (T)valueObj;
26 | return true;
27 | }
28 |
29 | value = default(T);
30 | return false;
31 | }
32 |
33 | ///
34 | /// Gets a value from the dictionary with given key. Returns default value if can not find.
35 | ///
36 | /// Dictionary to check and get
37 | /// Key to find the value
38 | /// Type of the key
39 | /// Type of the value
40 | /// Value if found, default if can not found.
41 | public static TValue GetOrDefault(this IDictionary dictionary, TKey key)
42 | {
43 | TValue obj;
44 | return dictionary.TryGetValue(key, out obj) ? obj : default(TValue);
45 | }
46 |
47 | ///
48 | /// Gets a value from the dictionary with given key. Returns default value if can not find.
49 | ///
50 | /// Dictionary to check and get
51 | /// Key to find the value
52 | /// A factory method used to create the value if not found in the dictionary
53 | /// Type of the key
54 | /// Type of the value
55 | /// Value if found, default if can not found.
56 | public static TValue GetOrAdd(this IDictionary dictionary, TKey key, Func factory)
57 | {
58 | TValue obj;
59 | if (dictionary.TryGetValue(key, out obj))
60 | {
61 | return obj;
62 | }
63 |
64 | return dictionary[key] = factory(key);
65 | }
66 |
67 | ///
68 | /// Gets a value from the dictionary with given key. Returns default value if can not find.
69 | ///
70 | /// Dictionary to check and get
71 | /// Key to find the value
72 | /// A factory method used to create the value if not found in the dictionary
73 | /// Type of the key
74 | /// Type of the value
75 | /// Value if found, default if can not found.
76 | public static TValue GetOrAdd(this IDictionary dictionary, TKey key, Func factory)
77 | {
78 | return dictionary.GetOrAdd(key, k => factory());
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Magicodes.SwaggerUI
2 | 通过配置文件简单配置即可快速完成SwaggerUI的配置,包括:
3 | - SwaggerUI的文档信息
4 | - API分组
5 | - API隐藏
6 | - API JSON生成(枚举、API架构Id)
7 | - 验证
8 | - 自定义页面
9 |
10 | 支持.NET Core 2.2和3.1。版本日志和使用教程见下文。
11 |
12 | 注意:AddCustomSwaggerGen和UseCustomSwaggerUI已分别替换为“AddMagicodesSwaggerGen”、“UseMagicodesSwaggerUI”。
13 |
14 | ## 特点
15 | - 通过配置文件简单配置即可完成SwaggerUI的API格式JSON生成和集成
16 | 
17 | - 支持API分组和隐藏
18 | 
19 | 
20 | - 支持自定义页面和验证
21 |
22 | ## Nuget包
23 |
24 | | 名称 | Nuget |
25 | |----------|:-------------:|
26 | | Magicodes.SwaggerUI | [](https://www.nuget.org/packages/Magicodes.SwaggerUI) |
27 |
28 | ### Magicodes Nuget包推荐
29 |
30 | ## 相关Nuget包
31 |
32 | | 名称 | 说明 | Nuget | GitHUb |
33 | |----------|:-------------:|:-------------:|:-------------:|
34 | | Magicodes.IE.Excel |Excel导入导出| [](https://www.nuget.org/packages/Magicodes.IE.Excel) |[dotnetcore](https://github.com/dotnetcore)/**[Magicodes.IE](https://github.com/dotnetcore/Magicodes.IE)**|
35 | | Magicodes.IE.Core |导入导出核心库| [](https://www.nuget.org/packages/Magicodes.IE.Core) |[dotnetcore](https://github.com/dotnetcore)/**[Magicodes.IE](https://github.com/dotnetcore/Magicodes.IE)**|
36 | | Magicodes.IE.HTML | HTML导入导出|[](https://www.nuget.org/packages/Magicodes.IE.HTML) |[dotnetcore](https://github.com/dotnetcore)/**[Magicodes.IE](https://github.com/dotnetcore/Magicodes.IE)**|
37 | | Magicodes.IE.Pdf |Pdf导出| [](https://www.nuget.org/packages/Magicodes.IE.Pdf) |[dotnetcore](https://github.com/dotnetcore)/**[Magicodes.IE](https://github.com/dotnetcore/Magicodes.IE)**|
38 | | Magicodes.IE.Word |Word导出| [](https://www.nuget.org/packages/Magicodes.IE.Word) |[dotnetcore](https://github.com/dotnetcore)/**[Magicodes.IE](https://github.com/dotnetcore/Magicodes.IE)**|
39 | | Magicodes.IE.Csv |Csv导入导出| [](https://www.nuget.org/packages/Magicodes.IE.Csv) |[dotnetcore](https://github.com/dotnetcore)/**[Magicodes.IE](https://github.com/dotnetcore/Magicodes.IE)**|
40 | | Magicodes.WeChat.MiniProgram |小程序SDK |[](https://www.nuget.org/packages/Magicodes.WeChat.MiniProgram) |**[Magicodes.WxMiniProgram.Sdk](https://github.com/xin-lai/Magicodes.WxMiniProgram.Sdk)**|
41 | | Magicodes.Sms.Aliyun |阿里云短信 | [](https://www.nuget.org/packages/Magicodes.Sms.Aliyun) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Sms](https://github.com/xin-lai/Magicodes.Sms)**|
42 | | Magicodes.Sms.Core | 短信核心库 | [](https://www.nuget.org/packages/Magicodes.Sms.Core) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Sms](https://github.com/xin-lai/Magicodes.Sms)**|
43 | | Magicodes.Sms.Aliyun.Abp | 阿里云短信Abp模块 | [](https://www.nuget.org/packages/Magicodes.Sms.Aliyun.Abp) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Sms](https://github.com/xin-lai/Magicodes.Sms)**|
44 | | Magicodes.Storage.Core |通用存储核心库| [](https://www.nuget.org/packages/Magicodes.Storage.Core) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Storage](https://github.com/xin-lai/Magicodes.Storage)**|
45 | | Magicodes.Storage.AliyunOss.Core |阿里云OSS存储| [](https://www.nuget.org/packages/Magicodes.Storage.AliyunOss.Core) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Storage](https://github.com/xin-lai/Magicodes.Storage)**|
46 | | Magicodes.Storage.Local.Core |本地存储| [](https://www.nuget.org/packages/Magicodes.Storage.Local.Core) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Storage](https://github.com/xin-lai/Magicodes.Storage)**|
47 | | Magicodes.Storage.Tencent.Core |腾讯云存储| [](https://www.nuget.org/packages/Magicodes.Storage.Tencent.Core) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Storage](https://github.com/xin-lai/Magicodes.Storage)**|
48 | | Magicodes.Storage.Abp.Core | 通用存储ABP模块集成| [](https://www.nuget.org/packages/Magicodes.Storage.Abp.Core) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Storage](https://github.com/xin-lai/Magicodes.Storage)**|
49 | | Magicodes.WeChat.SDK.Core |微信SDK | [](https://www.nuget.org/packages/Magicodes.WeChat.SDK.Core) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.WeChat.SDK](https://github.com/xin-lai/Magicodes.WeChat.SDK)**|
50 | | Magicodes.SwaggerUI |SwaggerUI API快速配置和分组| [](https://www.nuget.org/packages/Magicodes.SwaggerUI) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.SwaggerUI](https://github.com/xin-lai/Magicodes.SwaggerUI)**|
51 | | Magicodes.Pay.Alipay |支付宝支付库| [](https://www.nuget.org/packages/Magicodes.Pay.Alipay) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
52 | | Magicodes.Pay.Notify |支付通用回调库| [](https://www.nuget.org/packages/Magicodes.Pay.Notify) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
53 | | Magicodes.Pay.Wxpay |微信支付库| [](https://www.nuget.org/packages/Magicodes.Pay.Wxpay) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
54 | | Magicodes.Pay.Alipay.Global |国际支付宝支付库 | [](https://www.nuget.org/packages/Magicodes.Pay.Alipay.Global) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
55 | | Magicodes.Pay.Allinpay | 通联支付库 | [](https://www.nuget.org/packages/Magicodes.Pay.Allinpay) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
56 | | Magicodes.Pay.Abp | ABP 支付通用封装库| [](https://www.nuget.org/packages/Magicodes.Pay.Abp) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
57 | | Magicodes.Pay.Abp.Allinpay |ABP 通联支付模块| [](https://www.nuget.org/packages/Magicodes.Pay.Abp.Allinpay) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
58 | | Magicodes.Pay.Abp.Wxpay | ABP 微信支付模块| [](https://www.nuget.org/packages/Magicodes.Pay.Abp.Wxpay) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
59 | | Magicodes.Pay.Alipay.Global | ABP 国际支付宝模块 | [](https://www.nuget.org/packages/Magicodes.Pay.Alipay.Global) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
60 | | Magicodes.Pay.Alipay | ABP 支付宝模块 | [](https://www.nuget.org/packages/Magicodes.Pay.Alipay) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.Pay](https://github.com/xin-lai/Magicodes.Pay)**|
61 | | Magicodes.Abp.Castle.NLog | ABP Nlog支持模块 | [](https://www.nuget.org/packages/Magicodes.Abp.Castle.NLog) |[xin-lai](https://github.com/xin-lai)/**[Abp.Castle.NLog](https://github.com/xin-lai/Abp.Castle.NLog)**|
62 | | Magicodes.WxMiniProgram.Sdk |微信小程序SDK| [](https://www.nuget.org/packages/Magicodes.WxMiniProgram.Sdk) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.WxMiniProgram.Sdk](https://github.com/xin-lai/Magicodes.WxMiniProgram.Sdk)**|
63 | | Magicodes.WxMiniProgram.Sdk.Abp |微信小程序SDK Abp模块| [](https://www.nuget.org/packages/Magicodes.WxMiniProgram.Sdk.Abp) |[xin-lai](https://github.com/xin-lai)/**[Magicodes.WxMiniProgram.Sdk](https://github.com/xin-lai/Magicodes.WxMiniProgram.Sdk)**|
64 | | Magicodes.Dingtalk.SDK |钉钉SDK| [](https://www.nuget.org/packages/Magicodes.Dingtalk.SDK) | [xin-lai](https://github.com/xin-lai)/**[Magicodes.Dingtalk.SDK](https://github.com/xin-lai/Magicodes.Dingtalk.SDK)**|
65 | | Magicodes.DynamicSqlApi.Core | 根据SQL自动解析生成动态API | [](https://www.nuget.org/packages/Magicodes.DynamicSqlApi.Core) | **[Magicodes.DynamicSqlApi](https://github.com/xin-lai/Magicodes.DynamicSqlApi)** |
66 | | Magicodes.DynamicSqlApi.All | 根据SQL自动解析生成动态API | [](https://www.nuget.org/packages/Magicodes.DynamicSqlApi.All) | **[Magicodes.DynamicSqlApi](https://github.com/xin-lai/Magicodes.DynamicSqlApi)** |
67 | | Magicodes.DynamicSqlApi.CsScript |根据SQL自动解析生成动态API | [](https://www.nuget.org/packages/Magicodes.DynamicSqlApi.CsScript) | **[Magicodes.DynamicSqlApi](https://github.com/xin-lai/Magicodes.DynamicSqlApi)** |
68 | | Magicodes.DynamicSqlApi.Dapper | 根据SQL自动解析生成动态API | [](https://www.nuget.org/packages/Magicodes.DynamicSqlApi.Dapper) | **[Magicodes.DynamicSqlApi](https://github.com/xin-lai/Magicodes.DynamicSqlApi)** |
69 | | Magicodes.DynamicSqlApi.SqlServer | 根据SQL自动解析生成动态API | [](https://www.nuget.org/packages/Magicodes.DynamicSqlApi.SqlServer) | **[Magicodes.DynamicSqlApi](https://github.com/xin-lai/Magicodes.DynamicSqlApi)** |
70 |
71 | ## 联系我们
72 |
73 | > #### 订阅号
74 |
75 | 关注“麦扣聊技术”微信订阅号可以获得最新文章、教程、文档。
76 |
77 | 
78 |
79 |
80 | > #### QQ群
81 |
82 | - 编程交流群<85318032>
83 |
84 | - 产品交流群<897857351>
85 |
86 | > #### 文档官网&官方博客
87 |
88 | - 文档官网:
89 | - 博客:
90 |
91 |
92 | > #### 其他开源库
93 |
94 | -
95 | -
96 |
97 | ## 更新日志
98 |
99 | ### 2019.03.07
100 |
101 | - 【Nuget】Magicodes.SwaggerUI 3.0.2
102 | - 【升级】支持.NET Core 3.1
103 | - 【重构】支持自定义逻辑编写:
104 | - AddMagicodesSwaggerGen添加Action参数,可以实现自定义逻辑
105 | - UseMagicodesSwaggerUI添加Action参数,可以实现自定义逻辑
106 |
107 | ### 2019.10.21
108 |
109 | - 【Nuget】Magicodes.SwaggerUI 2.0.4
110 | - 【升级】单个文档不分组,显示所有API
111 | - 【梳理】梳理目录结构
112 | - 【修复】修复本地开发环境运行时不加载文档注释的问题
113 | - 【修改】自动移除GroupUrlPrefix的前后空格以及“/”前缀
114 | - 【升级】在全局隐藏API的基础上,支持分组API隐藏
115 | - 【升级】API隐藏支持HTTP方法配置,默认“*”
116 |
117 | ### 2019.10.19
118 | - 【升级】支持API分组,支持非侵入式配置,无需修改代码,仅通过配置即可完成API分组(见下面示例)
119 | - 【重构】重构整体逻辑
120 |
121 | ## Demo
122 | ### 配置Demo
123 | ```
124 | "SwaggerDoc": {
125 | "IsEnabled": "true",
126 | //将枚举值以字符串显示
127 | "DescribeAllEnumsAsStrings": false,
128 | "SwaggerDocInfos": [
129 | {
130 | "IsEnabled": "true",
131 | "Title": "APP1 API文档",
132 | "Version": "v1",
133 | "GroupName": "App1",
134 | "Description": "",
135 | "Contact": {
136 | "Name": "心莱科技Team1",
137 | "Email": "xinlai@xin-lai.com"
138 | },
139 | "GroupUrlPrefix": "api/app1/"
140 | },
141 | {
142 | "IsEnabled": "true",
143 | "Title": "APP2 API文档",
144 | "Version": "v2",
145 | "GroupName": "App2",
146 | "Description": "",
147 | "Contact": {
148 | "Name": "心莱科技Team2",
149 | "Email": "xinlai@xin-lai.com"
150 | },
151 | "GroupUrlPrefix": "api/app2/",
152 | "HiddenApi": {
153 | "IsEnabled": "true",
154 | "Urls": [
155 | {
156 | "Url": "app2/Values/{id}",
157 | "HttpMethod": "Delete"
158 | }
159 | ]
160 | }
161 | }
162 | ],
163 | "HiddenApi": {
164 | "IsEnabled": "true",
165 | "Urls": [
166 | { "Url": "app1/Values/{id}" }
167 | ]
168 | },
169 | "UseFullNameForSchemaId": "false"
170 | }
171 | ```
172 |
173 | ### 注入代码:
174 |
175 | ```
176 | //添加自定义API文档生成(支持文档配置)
177 | public IServiceProvider ConfigureServices(IServiceCollection services)
178 | {
179 | services.AddMagicodesSwaggerGen(_appConfiguration);
180 | }
181 |
182 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
183 | {
184 | //启用自定义API文档(支持文档配置)
185 | app.UseMagicodesSwaggerUI(_appConfiguration);
186 | }
187 | ```
--------------------------------------------------------------------------------
/src/Magicodes.SwaggerUI/Extentions.cs:
--------------------------------------------------------------------------------
1 | using Magicodes.SwaggerUI.Models;
2 | using Microsoft.AspNetCore.Builder;
3 | using Microsoft.AspNetCore.Mvc.ApiExplorer;
4 | using Microsoft.Extensions.Configuration;
5 | using Microsoft.Extensions.DependencyInjection;
6 | #if NETCOREAPP3_1
7 | using Microsoft.OpenApi.Models;
8 | #endif
9 | using Swashbuckle.AspNetCore.Swagger;
10 | using Swashbuckle.AspNetCore.SwaggerGen;
11 | using Swashbuckle.AspNetCore.SwaggerUI;
12 | using System;
13 | using System.Collections.Generic;
14 | using System.IO;
15 | using System.Linq;
16 | using System.Reflection;
17 |
18 | namespace Magicodes.SwaggerUI
19 | {
20 | ///
21 | ///
22 | ///
23 | public static class Extentions
24 | {
25 | #if NETCOREAPP3_1
26 | ///
27 | /// 添加自定义API文档生成(支持文档配置)
28 | ///
29 | ///
30 | ///
31 | public static void AddMagicodesSwaggerGen(this IServiceCollection services, IConfiguration configuration, Action setupAction = null)
32 | {
33 | var docConfigInfo = GetApiDocsConfigInfo(configuration);
34 | if (docConfigInfo == null)
35 | {
36 | return;
37 | }
38 | var webRootDirectory = GetRootPath();
39 | //设置API文档生成
40 | services.AddSwaggerGen(options =>
41 | {
42 | options.OperationFilter();
43 | options.OperationFilter();
44 | options.ParameterFilter();
45 | options.CustomDefaultSchemaIdSelector();
46 | //将所有枚举显示为字符串
47 | if (docConfigInfo.DescribeAllEnumsAsStrings)
48 | {
49 | options.SchemaFilter();
50 | }
51 |
52 | if (docConfigInfo.Authorize)
53 | {
54 | //以便于在界面上显示验证(Authorize)按钮,验证按钮处理逻辑基于 wwwroot/swagger/ui/index.html
55 | options.AddSecurityDefinition("Bearer",
56 | new Microsoft.OpenApi.Models.OpenApiSecurityScheme
57 | {
58 | In = Microsoft.OpenApi.Models.ParameterLocation.Header,
59 | Description = "Please enter into field the word 'Bearer' following by space and JWT",
60 | Name = "Authorization",
61 | Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey
62 | });
63 | options.AddSecurityRequirement(new OpenApiSecurityRequirement()
64 | {
65 | {
66 | new OpenApiSecurityScheme
67 | {
68 | Reference = new OpenApiReference
69 | {
70 | Type = ReferenceType.SecurityScheme,
71 | Id = "Bearer"
72 | },
73 | Scheme = "oauth2",
74 | Name = "Bearer",
75 | In = ParameterLocation.Header,
76 |
77 | },
78 | new List()
79 | }
80 | });
81 | }
82 |
83 | if (docConfigInfo.UseFullNameForSchemaId)
84 | {
85 | //使用全名作为架构id
86 | options.CustomSchemaIds(p => p.FullName);
87 | }
88 |
89 | foreach (var doc in docConfigInfo.SwaggerDocInfos)
90 | {
91 | options.SwaggerDoc(doc.GroupName ?? doc.Version, new Microsoft.OpenApi.Models.OpenApiInfo
92 | {
93 | Title = doc.Title,
94 | Version = doc.Version,
95 | Description = doc.Description,
96 | Contact = new Microsoft.OpenApi.Models.OpenApiContact
97 | {
98 | Name = doc.Contact?.Name,
99 | Email = doc.Contact?.Email
100 | }
101 | });
102 | }
103 |
104 | //遍历所有xml并加载
105 | var paths = new List();
106 | var plusPath = Path.Combine(webRootDirectory ?? throw new InvalidOperationException(), "PlugIns");
107 | if (Directory.Exists(plusPath))
108 | {
109 | var xmlFiles = new DirectoryInfo(plusPath).GetFiles("*.xml");
110 | paths.AddRange(xmlFiles.Select(item => item.FullName));
111 | }
112 | var binXmlFiles = new DirectoryInfo(webRootDirectory).GetFiles("*.xml", SearchOption.TopDirectoryOnly);
113 | paths.AddRange(binXmlFiles.Select(item => item.FullName));
114 |
115 | foreach (var filePath in paths)
116 | {
117 | options.IncludeXmlComments(filePath);
118 | }
119 |
120 | //接口分组和隐藏处理
121 | options.DocInclusionPredicate((docName, apiDescription) =>
122 | {
123 | //全局API隐藏逻辑处理
124 | if (IsHiddenApi(docConfigInfo.HiddenApi, apiDescription)) return false;
125 |
126 | //只有一个配置则不分组
127 | if (docConfigInfo.SwaggerDocInfos.Count <= 1)
128 | {
129 | return true;
130 | }
131 |
132 | var doc = docConfigInfo.SwaggerDocInfos.FirstOrDefault(p =>
133 | p.GroupName == docName);
134 | if (doc == null)
135 | {
136 | return false;
137 | }
138 |
139 | //分组API隐藏逻辑处理
140 | if (IsHiddenApi(doc.HiddenApi, apiDescription)) return false;
141 |
142 | //API分组处理
143 | if (!string.IsNullOrEmpty(doc.GroupUrlPrefix))
144 | {
145 | //分组处理:隐藏组Url不一致的接口
146 | return apiDescription.RelativePath.StartsWith(doc.GroupUrlPrefix,
147 | StringComparison.OrdinalIgnoreCase);
148 | }
149 | return false;
150 |
151 | });
152 |
153 | setupAction?.Invoke(options, docConfigInfo);
154 | });
155 | }
156 | #else
157 | ///
158 | /// 添加自定义API文档生成(支持文档配置)
159 | ///
160 | ///
161 | ///
162 | public static void AddMagicodesSwaggerGen(this IServiceCollection services, IConfiguration configuration,Action setupAction = null)
163 | {
164 | var docConfigInfo = GetApiDocsConfigInfo(configuration);
165 | if (docConfigInfo == null)
166 | {
167 | return;
168 | }
169 | var webRootDirectory = GetRootPath();
170 | //设置API文档生成
171 | services.AddSwaggerGen(options =>
172 | {
173 | //将所有枚举显示为字符串
174 | if (docConfigInfo.DescribeAllEnumsAsStrings)
175 | {
176 | options.DescribeAllEnumsAsStrings();
177 | }
178 |
179 | if (docConfigInfo.Authorize)
180 | {
181 | //以便于在界面上显示验证(Authorize)按钮,验证按钮处理逻辑基于 wwwroot/swagger/ui/index.html
182 | options.AddSecurityDefinition("Bearer", new BasicAuthScheme());
183 | }
184 |
185 | if (docConfigInfo.UseFullNameForSchemaId)
186 | {
187 | //使用全名作为架构id
188 | options.CustomSchemaIds(p => p.FullName);
189 | }
190 |
191 | foreach (var doc in docConfigInfo.SwaggerDocInfos)
192 | {
193 | options.SwaggerDoc(doc.GroupName ?? doc.Version, new Info
194 | {
195 | Title = doc.Title,
196 | Version = doc.Version,
197 | Description = doc.Description,
198 | Contact = new Contact
199 | {
200 | Name = doc.Contact?.Name,
201 | Email = doc.Contact?.Email
202 | }
203 | });
204 | }
205 |
206 | //遍历所有xml并加载
207 | var paths = new List();
208 | var plusPath = Path.Combine(webRootDirectory ?? throw new InvalidOperationException(), "PlugIns");
209 | if (Directory.Exists(plusPath))
210 | {
211 | var xmlFiles = new DirectoryInfo(plusPath).GetFiles("*.xml");
212 | paths.AddRange(xmlFiles.Select(item => item.FullName));
213 | }
214 | var binXmlFiles = new DirectoryInfo(webRootDirectory).GetFiles("*.xml", SearchOption.TopDirectoryOnly);
215 | paths.AddRange(binXmlFiles.Select(item => item.FullName));
216 |
217 | foreach (var filePath in paths)
218 | {
219 | options.IncludeXmlComments(filePath);
220 | }
221 |
222 | //接口分组和隐藏处理
223 | options.DocInclusionPredicate((docName, apiDescription) =>
224 | {
225 | //全局API隐藏逻辑处理
226 | if (IsHiddenApi(docConfigInfo.HiddenApi, apiDescription)) return false;
227 |
228 | //只有一个配置则不分组
229 | if (docConfigInfo.SwaggerDocInfos.Count <= 1)
230 | {
231 | return true;
232 | }
233 |
234 | var doc = docConfigInfo.SwaggerDocInfos.FirstOrDefault(p =>
235 | p.GroupName == docName);
236 | if (doc == null)
237 | {
238 | return false;
239 | }
240 |
241 | //分组API隐藏逻辑处理
242 | if (IsHiddenApi(doc.HiddenApi, apiDescription)) return false;
243 |
244 | //API分组处理
245 | if (!string.IsNullOrEmpty(doc.GroupUrlPrefix))
246 | {
247 | //分组处理:隐藏组Url不一致的接口
248 | return apiDescription.RelativePath.StartsWith(doc.GroupUrlPrefix,
249 | StringComparison.OrdinalIgnoreCase);
250 | }
251 | return false;
252 |
253 | });
254 |
255 | setupAction?.Invoke(options, docConfigInfo);
256 | });
257 | }
258 |
259 |
260 | #endif
261 |
262 |
263 | ///
264 | /// 是否隐藏此API
265 | ///
266 | ///
267 | ///
268 | ///
269 | private static bool IsHiddenApi(HiddenApiConfigInfo hiddenApiConfigInfo, ApiDescription apiDescription)
270 | {
271 | if (hiddenApiConfigInfo != null && hiddenApiConfigInfo.IsEnabled && hiddenApiConfigInfo.Urls != null && hiddenApiConfigInfo.Urls.Any())
272 | {
273 | foreach (var item in hiddenApiConfigInfo.Urls)
274 | {
275 | if (apiDescription.RelativePath.IndexOf(item.Url?.Trim(), StringComparison.OrdinalIgnoreCase) != -1 && (item.HttpMethod == "*" || apiDescription.HttpMethod.Equals(item.HttpMethod, StringComparison.OrdinalIgnoreCase)))
276 | {
277 | return true;
278 | }
279 | }
280 | }
281 | return false;
282 | }
283 |
284 | ///
285 | /// 获取文件根路径
286 | ///
287 | ///
288 | private static string GetRootPath()
289 | {
290 | var path = AppDomain.CurrentDomain.BaseDirectory;
291 | if (string.IsNullOrWhiteSpace(path))
292 | {
293 | path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
294 | }
295 | return path;
296 | }
297 |
298 | ///
299 | /// 获取配置信息
300 | ///
301 | ///
302 | ///
303 | private static SwaggerConfigInfo GetApiDocsConfigInfo(IConfiguration configuration)
304 | {
305 | var configs = configuration?["SwaggerDoc:IsEnabled"] != null
306 | ? configuration.GetSection("SwaggerDoc").Get()
307 | : null;
308 | if (configs.SwaggerDocInfos != null)
309 | {
310 | foreach (var item in configs.SwaggerDocInfos)
311 | {
312 | if (!string.IsNullOrWhiteSpace(item.GroupUrlPrefix))
313 | {
314 | item.GroupUrlPrefix = item.GroupUrlPrefix.Trim().TrimStart('/');
315 | }
316 | }
317 | }
318 | return configs;
319 | }
320 |
321 | ///
322 | /// 启用自定义API文档(支持文档配置)
323 | ///
324 | ///
325 | ///
326 | public static void UseMagicodesSwaggerUI(this IApplicationBuilder app, IConfiguration configuration, Action setupAction = null)
327 | {
328 | var docConfigInfo = GetApiDocsConfigInfo(configuration);
329 | if (docConfigInfo == null)
330 | {
331 | return;
332 | }
333 |
334 | app.UseSwagger(c =>
335 | {
336 | if (docConfigInfo.SwaggerDocInfos.Count > 1)
337 | {
338 | c.RouteTemplate = "swagger/{documentName}/swagger.json";
339 | }
340 | });
341 | // 加载swagger-ui 资源 (HTML, JS, CSS etc.)
342 | app.UseSwaggerUI(options =>
343 | {
344 | foreach (var doc in docConfigInfo.SwaggerDocInfos)
345 | {
346 | options.SwaggerEndpoint($"/swagger/{doc.GroupName ?? doc.Version}/swagger.json", doc.Title ?? "App API V1");
347 | }
348 |
349 | //允许通过嵌入式资源配置首页
350 | if (!string.IsNullOrWhiteSpace(docConfigInfo.ManifestResourceUrl) && !string.IsNullOrWhiteSpace(docConfigInfo.ManifestResourceAssembly))
351 | {
352 | var resStream = Assembly.Load(docConfigInfo.ManifestResourceAssembly)
353 | .GetManifestResourceStream(docConfigInfo.ManifestResourceUrl);
354 | if (resStream == null)
355 | {
356 | throw new Exception($"{docConfigInfo.ManifestResourceUrl} 不存在,请检查!");
357 | }
358 | options.IndexStream = () => resStream;
359 | }
360 |
361 | setupAction?.Invoke(options, docConfigInfo);
362 | });
363 |
364 |
365 | }
366 |
367 | ///
368 | /// https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/752#issuecomment-467817189
369 | /// When Swashbuckle.AspNetCore 5.0 is released, we can remove it.
370 | ///
371 | ///
372 | public static void CustomDefaultSchemaIdSelector(this SwaggerGenOptions options)
373 | {
374 | string SchemaIdSelector(Type modelType)
375 | {
376 | if (!modelType.IsConstructedGenericType)
377 | {
378 | return modelType.Name;
379 | }
380 |
381 | var prefix = modelType.GetGenericArguments()
382 | .Select(SchemaIdSelector)
383 | .Aggregate((previous, current) => previous + current);
384 |
385 | return modelType.Name.Split('`').First() + "Of" + prefix;
386 | }
387 |
388 | options.CustomSchemaIds(SchemaIdSelector);
389 | }
390 | }
391 | }
392 |
--------------------------------------------------------------------------------