Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
089c238126 | ||
|
|
99fd092b24 | ||
|
|
1e9fb7d195 | ||
|
|
66cd518872 | ||
|
|
b7ae3cf42e | ||
|
|
311a886830 | ||
|
|
3c584c3a95 | ||
|
|
8a4066a40e | ||
|
|
35fa68cffc | ||
|
|
8ea53827f5 | ||
|
|
1d63f2c585 | ||
|
|
b0bbd40621 | ||
|
|
5ea5c57450 | ||
|
|
d108d99e32 | ||
|
|
a827c8965e | ||
|
|
88235bb283 | ||
|
|
3c9c7531c0 |
@@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.30330.147
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{929BB2D7-C678-4BE8-8AA9-F271A2AE4545}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{929BB2D7-C678-4BE8-8AA9-F271A2AE4545}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IGeekFan.AspNetCore.Knife4jUI", "src\IGeekFan.AspNetCore.SwaggerUI\IGeekFan.AspNetCore.Knife4jUI.csproj", "{4589D4A2-AAC0-40BD-8A8E-2EBB2B68DA22}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{75C51574-4CBD-403B-8182-8BF2A6DCFD43}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{75C51574-4CBD-403B-8182-8BF2A6DCFD43}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basic", "test\Basic\Basic.csproj", "{88972F96-96D7-40A7-90DA-ED04C9ED9B33}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Basic", "test\Basic\Basic.csproj", "{88972F96-96D7-40A7-90DA-ED04C9ED9B33}"
|
||||||
@@ -22,16 +20,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{C146
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SwaggerUI_IndexStream_Knife4jUI_Demo", "samples\SwaggerUI_IndexStream_Knife4jUI_Demo\SwaggerUI_IndexStream_Knife4jUI_Demo.csproj", "{1D6FD5CA-5D58-4895-8545-A93099CE1AD4}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SwaggerUI_IndexStream_Knife4jUI_Demo", "samples\SwaggerUI_IndexStream_Knife4jUI_Demo\SwaggerUI_IndexStream_Knife4jUI_Demo.csproj", "{1D6FD5CA-5D58-4895-8545-A93099CE1AD4}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IGeekFan.AspNetCore.Knife4jUI", "src\IGeekFan.AspNetCore.Knife4jUI\IGeekFan.AspNetCore.Knife4jUI.csproj", "{6C784918-BE29-4FEF-8AC3-9D34A38DE822}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{86851B6C-3504-4879-8464-1DB422D46BA0}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OAuth2Integration", "test\WebSites\OAuth2Integration\OAuth2Integration.csproj", "{9E8D8F42-33F0-4F2D-9B56-1AB1B33DE1FA}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NSwag.Swagger.Knife4jUI", "test\WebSites\NSwag.Swagger.Knife4jUI\NSwag.Swagger.Knife4jUI.csproj", "{42B4C1C3-AE38-47C7-AAAA-FE0FDA7DADEB}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{4589D4A2-AAC0-40BD-8A8E-2EBB2B68DA22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4589D4A2-AAC0-40BD-8A8E-2EBB2B68DA22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4589D4A2-AAC0-40BD-8A8E-2EBB2B68DA22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4589D4A2-AAC0-40BD-8A8E-2EBB2B68DA22}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{88972F96-96D7-40A7-90DA-ED04C9ED9B33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{88972F96-96D7-40A7-90DA-ED04C9ED9B33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{88972F96-96D7-40A7-90DA-ED04C9ED9B33}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{88972F96-96D7-40A7-90DA-ED04C9ED9B33}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{88972F96-96D7-40A7-90DA-ED04C9ED9B33}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{88972F96-96D7-40A7-90DA-ED04C9ED9B33}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -44,15 +46,30 @@ Global
|
|||||||
{1D6FD5CA-5D58-4895-8545-A93099CE1AD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1D6FD5CA-5D58-4895-8545-A93099CE1AD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1D6FD5CA-5D58-4895-8545-A93099CE1AD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1D6FD5CA-5D58-4895-8545-A93099CE1AD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1D6FD5CA-5D58-4895-8545-A93099CE1AD4}.Release|Any CPU.Build.0 = Release|Any CPU
|
{1D6FD5CA-5D58-4895-8545-A93099CE1AD4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6C784918-BE29-4FEF-8AC3-9D34A38DE822}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6C784918-BE29-4FEF-8AC3-9D34A38DE822}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6C784918-BE29-4FEF-8AC3-9D34A38DE822}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6C784918-BE29-4FEF-8AC3-9D34A38DE822}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9E8D8F42-33F0-4F2D-9B56-1AB1B33DE1FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9E8D8F42-33F0-4F2D-9B56-1AB1B33DE1FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9E8D8F42-33F0-4F2D-9B56-1AB1B33DE1FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9E8D8F42-33F0-4F2D-9B56-1AB1B33DE1FA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{42B4C1C3-AE38-47C7-AAAA-FE0FDA7DADEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{42B4C1C3-AE38-47C7-AAAA-FE0FDA7DADEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{42B4C1C3-AE38-47C7-AAAA-FE0FDA7DADEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{42B4C1C3-AE38-47C7-AAAA-FE0FDA7DADEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{4589D4A2-AAC0-40BD-8A8E-2EBB2B68DA22} = {929BB2D7-C678-4BE8-8AA9-F271A2AE4545}
|
|
||||||
{88972F96-96D7-40A7-90DA-ED04C9ED9B33} = {75C51574-4CBD-403B-8182-8BF2A6DCFD43}
|
{88972F96-96D7-40A7-90DA-ED04C9ED9B33} = {75C51574-4CBD-403B-8182-8BF2A6DCFD43}
|
||||||
{86A24FA0-E85D-4BDD-97D7-B990C50A40A9} = {75C51574-4CBD-403B-8182-8BF2A6DCFD43}
|
{86A24FA0-E85D-4BDD-97D7-B990C50A40A9} = {75C51574-4CBD-403B-8182-8BF2A6DCFD43}
|
||||||
{1D6FD5CA-5D58-4895-8545-A93099CE1AD4} = {C146A419-15E0-4475-9623-706C5E2DCE0B}
|
{1D6FD5CA-5D58-4895-8545-A93099CE1AD4} = {C146A419-15E0-4475-9623-706C5E2DCE0B}
|
||||||
|
{6C784918-BE29-4FEF-8AC3-9D34A38DE822} = {929BB2D7-C678-4BE8-8AA9-F271A2AE4545}
|
||||||
|
{86851B6C-3504-4879-8464-1DB422D46BA0} = {75C51574-4CBD-403B-8182-8BF2A6DCFD43}
|
||||||
|
{9E8D8F42-33F0-4F2D-9B56-1AB1B33DE1FA} = {86851B6C-3504-4879-8464-1DB422D46BA0}
|
||||||
|
{42B4C1C3-AE38-47C7-AAAA-FE0FDA7DADEB} = {86851B6C-3504-4879-8464-1DB422D46BA0}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {9D77CCB4-F597-421B-9EF9-52D4B0AC382D}
|
SolutionGuid = {9D77CCB4-F597-421B-9EF9-52D4B0AC382D}
|
||||||
|
|||||||
66
README.md
@@ -20,17 +20,30 @@
|
|||||||
|
|
||||||
### 🚀安装包
|
### 🚀安装包
|
||||||
|
|
||||||
|
以下为使用Swashbuckle.AspNetCore.Swagger底层组件
|
||||||
|
|
||||||
1.Install the standard Nuget package into your ASP.NET Core application.
|
1.Install the standard Nuget package into your ASP.NET Core application.
|
||||||
|
|
||||||
```
|
```
|
||||||
Package Manager : Install-Package IGeekFan.AspNetCore.Knife4jUI
|
Package Manager :
|
||||||
CLI : dotnet add package IGeekFan.AspNetCore.Knife4jUI
|
|
||||||
|
Install-Package Swashbuckle.AspNetCore.Swagger
|
||||||
|
Install-Package Swashbuckle.AspNetCore.SwaggerGen
|
||||||
|
Install-Package IGeekFan.AspNetCore.Knife4jUI
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
CLI :
|
||||||
|
|
||||||
|
dotnet add package Swashbuckle.AspNetCore.Swagger
|
||||||
|
dotnet add package Swashbuckle.AspNetCore.SwaggerGen
|
||||||
|
dotnet add package IGeekFan.AspNetCore.Knife4jUI
|
||||||
```
|
```
|
||||||
|
|
||||||
2.In the ConfigureServices method of Startup.cs, register the Swagger generator, defining one or more Swagger documents.
|
2.In the ConfigureServices method of Startup.cs, register the Swagger generator, defining one or more Swagger documents.
|
||||||
|
|
||||||
```
|
```
|
||||||
using System.Reflection;
|
using Microsoft.AspNetCore.Mvc.Controllers
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
using IGeekFan.AspNetCore.Knife4jUI;
|
using IGeekFan.AspNetCore.Knife4jUI;
|
||||||
@@ -49,7 +62,8 @@ using IGeekFan.AspNetCore.Knife4jUI;
|
|||||||
});
|
});
|
||||||
c.CustomOperationIds(apiDesc =>
|
c.CustomOperationIds(apiDesc =>
|
||||||
{
|
{
|
||||||
return apiDesc.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : null;
|
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
|
||||||
|
return controllerAction.ControllerName+"-"+controllerAction.ActionName;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@@ -72,6 +86,50 @@ app.UseEndpoints(endpoints =>
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
5.更多功能
|
||||||
|
|
||||||
|
为文档添加注释 在项目上右键--属性--生成
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
在AddSwaggerGen方法中添加如下代码
|
||||||
|
|
||||||
|
```
|
||||||
|
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "SwaggerDemo.xml"),true);
|
||||||
|
```
|
||||||
|
最后一个参数设置为true,代表启用控制器上的注释
|
||||||
|
|
||||||
|
运行后如看不到控制器上注释显示,请点开文档管理->个性化设置,开启分组tag显示description说明属性
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### NSwag.AspNetCore
|
||||||
|
(请参考目录test/WebSites/NSwag.Swagger.Knife4jUI)
|
||||||
|
|
||||||
|
```
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
// 其它Service
|
||||||
|
services.AddOpenApiDocument();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
// 其它 Use
|
||||||
|
app.UseOpenApi();
|
||||||
|
app.UseKnife4UI(c =>
|
||||||
|
{
|
||||||
|
c.RoutePrefix = "";
|
||||||
|
c.SwaggerEndpoint("/swagger/v1/swagger.json");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
即可使用 Knife4jUI
|
||||||
|
|
||||||
### 🔎 效果图
|
### 🔎 效果图
|
||||||
运行项目,打开 https://localhost:5001/index.html#/home
|
运行项目,打开 https://localhost:5001/index.html#/home
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||||
|
|
||||||
namespace Knife4jUIDemo
|
namespace Knife4jUIDemo
|
||||||
@@ -39,7 +38,8 @@ namespace Knife4jUIDemo
|
|||||||
});
|
});
|
||||||
c.CustomOperationIds(apiDesc =>
|
c.CustomOperationIds(apiDesc =>
|
||||||
{
|
{
|
||||||
return apiDesc.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : null;
|
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
|
||||||
|
return controllerAction.ControllerName + "-" + controllerAction.ActionName;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.5.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.1.4" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.5.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.1.4" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="5.5.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="6.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,38 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
|
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net5.0</TargetFrameworks>
|
||||||
<Description>Middleware to expose an embedded version of the knife4j-vue-v3 from an ASP.NET Core application</Description>
|
<Description>Middleware to expose an embedded version of the knife4j-vue-v3 from an ASP.NET Core application</Description>
|
||||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<PackageId></PackageId>
|
<PackageId>IGeekFan.AspNetCore.Knife4jUI</PackageId>
|
||||||
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore</PackageTags>
|
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore</PackageTags>
|
||||||
<PackageProjectUrl>https://github.com/luoyunchong/IGeekFan.AspNetCore.Knife4jUI</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/luoyunchong/IGeekFan.AspNetCore.Knife4jUI</PackageProjectUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<RepositoryUrl>https://github.com/luoyunchong/IGeekFan.AspNetCore.Knife4jUI.git</RepositoryUrl>
|
<RepositoryUrl>https://github.com/luoyunchong/IGeekFan.AspNetCore.Knife4jUI.git</RepositoryUrl>
|
||||||
<RootNamespace>IGeekFan.AspNetCore.Knife4jUI</RootNamespace>
|
<RootNamespace>IGeekFan.AspNetCore.Knife4jUI</RootNamespace>
|
||||||
<Version>0.0.2</Version>
|
<Version>0.0.10</Version>
|
||||||
<Company />
|
<Company />
|
||||||
<Authors>igeekfan;xiaoym;</Authors>
|
<Authors>igeekfan;xiaoym;</Authors>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Copyright>Apache License 2.0</Copyright>
|
<Copyright>Apache License 2.0</Copyright>
|
||||||
<PackageLicenseExpression></PackageLicenseExpression>
|
<PackageLicenseExpression></PackageLicenseExpression>
|
||||||
|
<AssemblyVersion>0.0.10.0</AssemblyVersion>
|
||||||
|
<FileVersion>0.0.10.0</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- Using SourceLink -->
|
||||||
|
<PropertyGroup>
|
||||||
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||||
|
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||||
|
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||||
|
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' ">
|
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' ">
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="2.1.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="2.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
|
||||||
@@ -26,13 +40,9 @@
|
|||||||
<PackageReference Include="System.Text.Json" Version="4.6.0" />
|
<PackageReference Include="System.Text.Json" Version="4.6.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">
|
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard2.0' ">
|
||||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.5.1" />
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.5.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="knife4j/**/*" />
|
<EmbeddedResource Include="knife4j/**/*" />
|
||||||
@@ -136,6 +136,8 @@ namespace IGeekFan.AspNetCore.Knife4jUI
|
|||||||
public string Url { get; set; }
|
public string Url { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string SwaggerVersion { get; set; } = "3.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ModelRendering
|
public enum ModelRendering
|
||||||
@@ -14,8 +14,8 @@ using System.Text.Json;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
#if NETCOREAPP3_0
|
#if NETSTANDARD2_0
|
||||||
using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IWebHostEnvironment;
|
using IWebHostEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment;
|
||||||
#endif
|
#endif
|
||||||
namespace IGeekFan.AspNetCore.Knife4jUI
|
namespace IGeekFan.AspNetCore.Knife4jUI
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@ namespace IGeekFan.AspNetCore.Knife4jUI
|
|||||||
|
|
||||||
public Knife4jUIMiddleware(
|
public Knife4jUIMiddleware(
|
||||||
RequestDelegate next,
|
RequestDelegate next,
|
||||||
IHostingEnvironment hostingEnv,
|
IWebHostEnvironment hostingEnv,
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory,
|
||||||
Knife4UIOptions options)
|
Knife4UIOptions options)
|
||||||
{
|
{
|
||||||
@@ -45,6 +45,7 @@ namespace IGeekFan.AspNetCore.Knife4jUI
|
|||||||
|
|
||||||
public async Task Invoke(HttpContext httpContext)
|
public async Task Invoke(HttpContext httpContext)
|
||||||
{
|
{
|
||||||
|
|
||||||
var httpMethod = httpContext.Request.Method;
|
var httpMethod = httpContext.Request.Method;
|
||||||
var path = httpContext.Request.Path.Value;
|
var path = httpContext.Request.Path.Value;
|
||||||
|
|
||||||
@@ -66,7 +67,7 @@ namespace IGeekFan.AspNetCore.Knife4jUI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpMethod == "GET" && Regex.IsMatch(path, $"^/v3/api-docs/swagger-config$"))
|
if (httpMethod == "GET" && Regex.IsMatch(path, $"/swagger-resources$"))
|
||||||
{
|
{
|
||||||
await RespondWithConfig(httpContext.Response);
|
await RespondWithConfig(httpContext.Response);
|
||||||
return;
|
return;
|
||||||
@@ -77,12 +78,12 @@ namespace IGeekFan.AspNetCore.Knife4jUI
|
|||||||
|
|
||||||
private async Task RespondWithConfig(HttpResponse response)
|
private async Task RespondWithConfig(HttpResponse response)
|
||||||
{
|
{
|
||||||
await response.WriteAsync(JsonSerializer.Serialize(_options.ConfigObject, _jsonSerializerOptions));
|
await response.WriteAsync(JsonSerializer.Serialize(_options.ConfigObject.Urls, _jsonSerializerOptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
private StaticFileMiddleware CreateStaticFileMiddleware(
|
private StaticFileMiddleware CreateStaticFileMiddleware(
|
||||||
RequestDelegate next,
|
RequestDelegate next,
|
||||||
IHostingEnvironment hostingEnv,
|
IWebHostEnvironment hostingEnv,
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory,
|
||||||
Knife4UIOptions options)
|
Knife4UIOptions options)
|
||||||
{
|
{
|
||||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
42
src/IGeekFan.AspNetCore.Knife4jUI/index.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang=en>
|
||||||
|
<head>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<meta http-equiv=X-UA-Compatible content="IE=edge">
|
||||||
|
<meta name=viewport content="width=device-width,initial-scale=1">
|
||||||
|
<link rel=icon href=favicon.ico>
|
||||||
|
<title>%(DocumentTitle)</title>
|
||||||
|
<link href=knife4j/css/chunk-51277dbe.57225f85.css rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-069eb437.0b47243d.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-0fd67716.d57e2c41.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-2d0af44e.c299c1d4.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-2d0bd799.cc91c520.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-2d0d0b98.cb1dea78.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-2d0da532.dd3c929c.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-2d22269d.bd9173e1.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-3b888a65.8737ce4f.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-3ec4aaa8.a79d19f8.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-51277dbe.4335d8bb.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-589faee0.b24e5f3d.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-735c675c.76ef1019.js rel=prefetch>
|
||||||
|
<link href=knife4j/js/chunk-adb9e944.b888f4bd.js rel=prefetch>
|
||||||
|
<link href=knife4j/css/app.284871fa.css rel=preload as=style>
|
||||||
|
<link href=knife4j/css/chunk-vendors.3f2387de.css rel=preload as=style>
|
||||||
|
<link href=knife4j/js/app.703cb2b2.js rel=preload as=script>
|
||||||
|
<link href=knife4j/js/chunk-vendors.90e8ba20.js rel=preload as=script>
|
||||||
|
<link href=knife4j/css/chunk-vendors.3f2387de.css rel=stylesheet>
|
||||||
|
<link href=knife4j/css/app.284871fa.css rel=stylesheet>
|
||||||
|
%(HeadContent)
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript><strong>We're sorry but knife4j-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
|
||||||
|
<div id=app></div>
|
||||||
|
<script src=knife4j/js/chunk-vendors.90e8ba20.js></script>
|
||||||
|
<script src=knife4j/js/app.703cb2b2.js></script>
|
||||||
|
<script>
|
||||||
|
window.onload = function () {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.api-tab[data-v-7da2228c]{margin-top:15px}.api-tab .ant-tag[data-v-7da2228c]{height:32px;line-height:32px}.api-basic[data-v-7da2228c]{padding:11px}.api-basic-title[data-v-7da2228c]{font-size:14px;font-weight:700}.api-basic-body[data-v-7da2228c]{font-size:14px;font-family:-webkit-body}.api-description[data-v-7da2228c]{border-left:4px solid #ddd;line-height:30px}.api-body-desc[data-v-7da2228c]{padding:10px;min-height:35px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #e8e8e8}.ant-card-body[data-v-7da2228c]{padding:5px}.api-title[data-v-7da2228c]{margin-top:10px;margin-bottom:5px;font-size:16px;font-weight:600;height:30px;line-height:30px;border-left:4px solid #00ab6d;text-indent:8px}.content-line[data-v-7da2228c]{height:25px;line-height:25px}.content-line-count[data-v-7da2228c]{height:35px;line-height:35px}.divider[data-v-7da2228c]{margin:4px 0}
|
||||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 306 KiB After Width: | Height: | Size: 306 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
BIN
src/IGeekFan.AspNetCore.Knife4jUI/knife4j/js/app.703cb2b2.js.gz
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-2d0af44e"],{"0e36":function(e,t,i){"use strict";i.r(t);var n={name:"EditorShow",components:{editor:i("7c9e")},props:{value:{type:String,required:!0,default:""},xmlMode:{type:Boolean,default:!1,required:!1}},data:function(){return{lang:"json",editor:null,editorHeight:200}},methods:{change:function(e){this.$emit("change",e)},resetEditorHeight:function(){var e=this;setTimeout((function(){var t=e.editor.session.getLength();1==t&&(t=10);var i=16*t;e.editorHeight=i}),300)},editorInit:function(e){var t=this;this.editor=e,i("2099"),i("818b"),i("0696"),this.xmlMode&&(this.lang="xml"),i("1d29"),this.resetEditorHeight(),this.editor.renderer.on("afterRender",(function(){t.$emit("showDescription","123")}))}}},o=i("2877"),r=Object(o.a)(n,(function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",[i("editor",{attrs:{value:e.value,lang:e.lang,theme:"eclipse",width:"100%",height:e.editorHeight},on:{init:e.editorInit,input:e.change}})],1)}),[],!1,null,null,null);t.default=r.exports}}]);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
(window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-2d0bd799"],{"2bc6":function(t,e,a){"use strict";a.r(e);var n={name:"DataType",props:{text:{type:String,default:"string",required:!0},record:{type:Object,required:!0}},data:function(){return{validators:[]}},created:function(){this.intiValidator()},methods:{intiValidator:function(){var t=this.record;if(null!=t.validateInstance)for(var e in this.getJsonKeyLength(t.validateInstance),t.validateInstance){var a=e+":"+t.validateInstance[e];this.validators.push({key:e,val:a})}},getJsonKeyLength:function(t){var e=0;if(null!=t)for(var a in t)t.hasOwnProperty(a)&&e++;return e}}},r=a("2877"),i=Object(r.a)(n,(function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",[t.record.validateStatus?a("span",{staticClass:"knife4j-request-validate-jsr"},[a("a-tooltip",{attrs:{placement:"right"}},[a("template",{slot:"title"},t._l(t.validators,(function(e){return a("div",{key:e.key},[t._v(t._s(e.val))])})),0),t._v(" "+t._s(t.text)+" ")],2)],1):a("span",[t._v(t._s(null==t.text||""==t.text?"string":t.text))])])}),[],!1,null,null,null);e.default=i.exports}}]);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
(window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-2d0d0b98"],{"68cc":function(n,e,t){"use strict";t.r(e);var s=t("0e54"),r=t.n(s);r.a.setOptions({gfm:!0,tables:!0,breaks:!1,pedantic:!1,sanitize:!1,smartLists:!0,smartypants:!1});var a={name:"Markdown",props:{source:{type:String}},computed:{markdownSource:function(){return r()(this.source)}}},o=t("2877"),c=Object(o.a)(a,(function(){var n=this,e=n.$createElement;return(n._self._c||e)("div",{staticClass:"knife4j-markdown",domProps:{innerHTML:n._s(n.markdownSource)}})}),[],!1,null,null,null);e.default=c.exports}}]);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
(window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-2d0da532"],{"6ab3":function(e,n,t){"use strict";t.r(n);var u=(t("5609"),t("b1c7"),{name:"OAuth2",components:{},data:function(){return{api:null,swaggerInstance:null,debugSupport:!1}},computed:{swagger:function(){return this.$store.state.globals.swagger}},mounted:function(){},beforeCreate:function(){},created:function(){},methods:{}}),a=t("2877"),o=Object(a.a)(u,(function(){var e=this,n=e.$createElement;return(e._self._c||n)("a-row",[e._v(" 我是OAuth2回调页面 ")])}),[],!1,null,"5ccd4e78",null);n.default=o.exports}}]);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
(window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-2d22269d"],{cf04:function(t,e,i){"use strict";i.r(e);var n={name:"EditorShow",components:{editor:i("7c9e")},props:{value:{type:String,required:!0,default:""}},data:function(){return{lang:"javascript",editor:null,editorHeight:200}},methods:{resetEditorHeight:function(){var t=this;setTimeout((function(){var e=t.editor.session.getLength();1==e&&(e=10);var i=16*e;t.editorHeight=i}),300)},change:function(t){this.$emit("change",t)},editorInit:function(t){var e=this;this.editor=t,i("2099"),i("bb36"),i("1d29"),this.resetEditorHeight(),this.editor.renderer.on("afterRender",(function(){e.$emit("showDescription","123")}))}}},r=i("2877"),o=Object(r.a)(n,(function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",[i("editor",{attrs:{value:t.value,lang:t.lang,theme:"eclipse",width:"100%",height:t.editorHeight},on:{init:t.editorInit,input:t.change}})],1)}),[],!1,null,null,null);e.default=o.exports}}]);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* clipboard.js v2.0.6
|
||||||
|
* https://clipboardjs.com/
|
||||||
|
*
|
||||||
|
* Licensed MIT © Zeno Rocha
|
||||||
|
*/
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* clipboard.js v2.0.6
|
||||||
|
* https://clipboardjs.com/
|
||||||
|
*
|
||||||
|
* Licensed MIT © Zeno Rocha
|
||||||
|
*/
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* clipboard.js v2.0.6
|
||||||
|
* https://clipboardjs.com/
|
||||||
|
*
|
||||||
|
* Licensed MIT © Zeno Rocha
|
||||||
|
*/
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
object-assign
|
||||||
|
(c) Sindre Sorhus
|
||||||
|
@license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
localForage -- Offline Storage, Improved
|
||||||
|
Version 1.9.0
|
||||||
|
https://localforage.github.io/localForage
|
||||||
|
(c) 2013-2017 Mozilla, Apache License 2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* vue-router v3.4.3
|
||||||
|
* (c) 2020 Evan You
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Copyright (c) 2017 Jed Watson.
|
||||||
|
Licensed under the MIT License (MIT), see
|
||||||
|
http://jedwatson.github.io/classnames
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The buffer module from node.js, for the browser.
|
||||||
|
*
|
||||||
|
* @author Feross Aboukhadijeh <http://feross.org>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Vue.js v2.6.12
|
||||||
|
* (c) 2014-2020 Evan You
|
||||||
|
* Released under the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* vue-i18n v8.21.0
|
||||||
|
* (c) 2020 kazuya kawaguchi
|
||||||
|
* Released under the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* vuex v3.5.1
|
||||||
|
* (c) 2020 Evan You
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */
|
||||||
|
|
||||||
|
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [js-md5]{@link https://github.com/emn178/js-md5}
|
||||||
|
*
|
||||||
|
* @namespace md5
|
||||||
|
* @version 0.7.3
|
||||||
|
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||||
|
* @copyright Chen, Yi-Cyuan 2014-2017
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
|
||||||
|
|
||||||
|
//! license : MIT
|
||||||
|
|
||||||
|
//! moment.js
|
||||||
|
|
||||||
|
//! moment.js language configuration
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
//! momentjs.com
|
||||||
|
|
||||||
|
//! version : 2.27.0
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
|
|
||||||
<Description>Middleware to expose an embedded version of the knife4j-vue-v3 from an ASP.NET Core application</Description>
|
|
||||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
|
||||||
<PackageId></PackageId>
|
|
||||||
<PackageTags>swagger;documentation;discovery;help;webapi;aspnet;aspnetcore</PackageTags>
|
|
||||||
<PackageProjectUrl>https://github.com/luoyunchong/IGeekFan.AspNetCore.Knife4jUI</PackageProjectUrl>
|
|
||||||
<RepositoryType>git</RepositoryType>
|
|
||||||
<RepositoryUrl>https://github.com/luoyunchong/IGeekFan.AspNetCore.Knife4jUI.git</RepositoryUrl>
|
|
||||||
<RootNamespace>IGeekFan.AspNetCore.Knife4jUI</RootNamespace>
|
|
||||||
<Version>0.0.1</Version>
|
|
||||||
<Company />
|
|
||||||
<Authors />
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="2.1.0" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.0" />
|
|
||||||
<PackageReference Include="System.Text.Json" Version="4.6.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">
|
|
||||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="IGeekFan.AspNetCore.Swagger" Version="5.5.1" />
|
|
||||||
<PackageReference Include="IGeekFan.AspNetCore.SwaggerGen" Version="5.5.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="knife4j/**/*" />
|
|
||||||
<EmbeddedResource Include="favicon.ico" />
|
|
||||||
<EmbeddedResource Include="index.html" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang=en>
|
|
||||||
<head>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<meta http-equiv=X-UA-Compatible content="IE=edge">
|
|
||||||
<meta name=viewport content="width=device-width,initial-scale=1">
|
|
||||||
<link rel=icon href=favicon.ico>
|
|
||||||
<title>%(DocumentTitle)</title>
|
|
||||||
<link href=knife4j/css/app.8f08f96a.css rel=preload as= style>
|
|
||||||
<link href=knife4j/js/app.c02977a4.js rel=preload as=script>
|
|
||||||
<link href=knife4j/js/chunk-vendors.e86fea24.js rel=preload as=script>
|
|
||||||
<link href=knife4j/css/app.8f08f96a.css rel=stylesheet>
|
|
||||||
%(HeadContent)
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript><strong>We're sorry but knife4j-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div>
|
|
||||||
<script src=knife4j/js/chunk-vendors.e86fea24.js></script>
|
|
||||||
<script src=knife4j/js/app.c02977a4.js></script>
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
object-assign
|
|
||||||
(c) Sindre Sorhus
|
|
||||||
@license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
localForage -- Offline Storage, Improved
|
|
||||||
Version 1.7.3
|
|
||||||
https://localforage.github.io/localForage
|
|
||||||
(c) 2013-2017 Mozilla, Apache License 2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* vue-router v3.1.6
|
|
||||||
* (c) 2020 Evan You
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Copyright (c) 2017 Jed Watson.
|
|
||||||
Licensed under the MIT License (MIT), see
|
|
||||||
http://jedwatson.github.io/classnames
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* The buffer module from node.js, for the browser.
|
|
||||||
*
|
|
||||||
* @author Feross Aboukhadijeh <http://feross.org>
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Vue.js v2.6.11
|
|
||||||
* (c) 2014-2019 Evan You
|
|
||||||
* Released under the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* clipboard.js v2.0.6
|
|
||||||
* https://clipboardjs.com/
|
|
||||||
*
|
|
||||||
* Licensed MIT © Zeno Rocha
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* html2canvas 1.0.0-rc.5 <https://html2canvas.hertzen.com>
|
|
||||||
* Copyright (c) 2019 Niklas von Hertzen <https://hertzen.com>
|
|
||||||
* Released under MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* vue-i18n v8.17.4
|
|
||||||
* (c) 2020 kazuya kawaguchi
|
|
||||||
* Released under the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! *****************************************************************************
|
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
||||||
this file except in compliance with the License. You may obtain a copy of the
|
|
||||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
||||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
||||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
||||||
|
|
||||||
See the Apache Version 2.0 License for specific language governing permissions
|
|
||||||
and limitations under the License.
|
|
||||||
***************************************************************************** */
|
|
||||||
|
|
||||||
/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */
|
|
||||||
|
|
||||||
/*! https://mths.be/punycode v1.4.1 by @mathias */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [js-md5]{@link https://github.com/emn178/js-md5}
|
|
||||||
*
|
|
||||||
* @namespace md5
|
|
||||||
* @version 0.7.3
|
|
||||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
|
||||||
* @copyright Chen, Yi-Cyuan 2014-2017
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vuex v3.3.0
|
|
||||||
* (c) 2020 Evan You
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.5.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.1.4" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="6.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -15,6 +16,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\IGeekFan.AspNetCore.SwaggerUI\IGeekFan.AspNetCore.Knife4jUI.csproj" />
|
<ProjectReference Include="..\..\src\IGeekFan.AspNetCore.Knife4jUI\IGeekFan.AspNetCore.Knife4jUI.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -26,6 +26,13 @@ namespace Basic.Controllers
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("form-with-user")]
|
||||||
|
public IActionResult PostFormUser([FromForm] FormUser FormUser)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("{name}")]
|
[HttpGet("{name}")]
|
||||||
[Produces("application/octet-stream", Type = typeof(FileResult))]
|
[Produces("application/octet-stream", Type = typeof(FileResult))]
|
||||||
public FileResult GetFile(string name)
|
public FileResult GetFile(string name)
|
||||||
@@ -47,4 +54,11 @@ namespace Basic.Controllers
|
|||||||
|
|
||||||
public IFormFile File { get; set; }
|
public IFormFile File { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class FormUser
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string User { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:53224"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Basic": {
|
"Basic": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@@ -10,13 +9,8 @@ using Microsoft.OpenApi.Models;
|
|||||||
using Basic.Swagger;
|
using Basic.Swagger;
|
||||||
using Microsoft.AspNetCore.Localization;
|
using Microsoft.AspNetCore.Localization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using System.Reflection;
|
|
||||||
using IGeekFan.AspNetCore.Knife4jUI;
|
using IGeekFan.AspNetCore.Knife4jUI;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
|
|
||||||
namespace Basic
|
namespace Basic
|
||||||
{
|
{
|
||||||
@@ -56,9 +50,9 @@ namespace Basic
|
|||||||
|
|
||||||
c.GeneratePolymorphicSchemas();
|
c.GeneratePolymorphicSchemas();
|
||||||
|
|
||||||
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Basic.xml"));
|
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Basic.xml"),true);
|
||||||
|
|
||||||
c.EnableAnnotations();
|
//c.EnableAnnotations();
|
||||||
c.AddServer(new OpenApiServer()
|
c.AddServer(new OpenApiServer()
|
||||||
{
|
{
|
||||||
Url = "",
|
Url = "",
|
||||||
@@ -66,7 +60,8 @@ namespace Basic
|
|||||||
});
|
});
|
||||||
c.CustomOperationIds(apiDesc =>
|
c.CustomOperationIds(apiDesc =>
|
||||||
{
|
{
|
||||||
return apiDesc.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : null;
|
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
|
||||||
|
return controllerAction.ControllerName + "-" + controllerAction.ActionName;
|
||||||
});
|
});
|
||||||
|
|
||||||
c.OrderActionsBy((apiDesc) => $"{apiDesc.ActionDescriptor.RouteValues["controller"]}_{apiDesc.HttpMethod}");
|
c.OrderActionsBy((apiDesc) => $"{apiDesc.ActionDescriptor.RouteValues["controller"]}_{apiDesc.HttpMethod}");
|
||||||
@@ -104,21 +99,26 @@ namespace Basic
|
|||||||
|
|
||||||
app.UseSwagger(c =>
|
app.UseSwagger(c =>
|
||||||
{
|
{
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.UseSwaggerUI(c =>
|
||||||
|
{
|
||||||
|
c.RoutePrefix = "swagger"; // serve the UI at root
|
||||||
|
c.SwaggerEndpoint("/v1/swagger.json", "V1 Docs");
|
||||||
|
c.SwaggerEndpoint("/gp/swagger.json", "<22><>¼ģ<C2BC><C4A3>");
|
||||||
|
});
|
||||||
app.UseKnife4UI(c =>
|
app.UseKnife4UI(c =>
|
||||||
{
|
{
|
||||||
c.RoutePrefix = ""; // serve the UI at root
|
c.RoutePrefix = ""; // serve the UI at root
|
||||||
c.SwaggerEndpoint("/v1/api-docs", "V1 Docs");
|
c.SwaggerEndpoint("/v1/swagger.json", "V1 Docs");
|
||||||
c.SwaggerEndpoint("/gp/api-docs", "<22><>¼ģ<C2BC><C4A3>");
|
c.SwaggerEndpoint("/gp/swagger.json", "<22><>¼ģ<C2BC><C4A3>");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
endpoints.MapSwagger("{documentName}/api-docs");
|
endpoints.MapSwagger("{documentName}/swagger.json");
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
using System;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Knife4jUIDemo.Controllers
|
namespace Knife4jUIDemo.Controllers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 中文这是一个Get请求这是一个Get请求
|
||||||
|
/// </summary>
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("[controller]")]
|
[Route("api/WeatherForecast/[action]")]
|
||||||
public class WeatherForecastController : ControllerBase
|
public class WeatherForecastController : ControllerBase
|
||||||
{
|
{
|
||||||
private static readonly string[] Summaries = new[]
|
private static readonly string[] Summaries = new[]
|
||||||
@@ -23,6 +25,42 @@ namespace Knife4jUIDemo.Controllers
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 得到一个ErrorCode
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
public ErrorCode GetErrorCode()
|
||||||
|
{
|
||||||
|
return ErrorCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public ErrorCode GetErrorCode2(ErrorCode errorCode)
|
||||||
|
{
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetErrorCode4(ErrorCode errorCode)
|
||||||
|
{
|
||||||
|
return new JsonResult(new PostErrorCodeDto() { Message="a",ErrorCode=errorCode});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送一个Post
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public PostErrorCodeDto PostErrorCode([FromBody] PostErrorCodeDto PostErrorCodeDto)
|
||||||
|
{
|
||||||
|
return PostErrorCodeDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 这是一个Get请求
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IEnumerable<WeatherForecast> Get()
|
public IEnumerable<WeatherForecast> Get()
|
||||||
{
|
{
|
||||||
@@ -36,4 +74,19 @@ namespace Knife4jUIDemo.Controllers
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求实体
|
||||||
|
/// </summary>
|
||||||
|
public class PostErrorCodeDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异常信息
|
||||||
|
/// </summary>
|
||||||
|
public string Message { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 状态码
|
||||||
|
/// </summary>
|
||||||
|
public ErrorCode ErrorCode { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
81
test/Knife4jUIDemo/ErrorCode.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace Knife4jUIDemo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 注释ErrorCode
|
||||||
|
/// </summary>
|
||||||
|
public enum ErrorCode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 操作成功
|
||||||
|
/// </summary>
|
||||||
|
Success = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// 未知错误
|
||||||
|
/// </summary>
|
||||||
|
UnknownError = 1007,
|
||||||
|
/// <summary>
|
||||||
|
/// 服务器未知错误
|
||||||
|
/// </summary>
|
||||||
|
ServerUnknownError = 999,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 失败
|
||||||
|
/// </summary>
|
||||||
|
Error = 1000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 认证失败
|
||||||
|
/// </summary>
|
||||||
|
AuthenticationFailed = 10000,
|
||||||
|
/// <summary>
|
||||||
|
/// 无权限
|
||||||
|
/// </summary>
|
||||||
|
NoPermission = 10001,
|
||||||
|
/// <summary>
|
||||||
|
/// 失败
|
||||||
|
/// </summary>
|
||||||
|
Fail = 9999,
|
||||||
|
/// <summary>
|
||||||
|
/// refreshToken异常
|
||||||
|
/// </summary>
|
||||||
|
RefreshTokenError = 10100,
|
||||||
|
/// <summary>
|
||||||
|
/// 资源不存在
|
||||||
|
/// </summary>
|
||||||
|
NotFound = 10020,
|
||||||
|
/// <summary>
|
||||||
|
/// 参数错误
|
||||||
|
/// </summary>
|
||||||
|
[Description("参数错误")]
|
||||||
|
ParameterError = 10030,
|
||||||
|
/// <summary>
|
||||||
|
/// 令牌失效
|
||||||
|
/// </summary>
|
||||||
|
[Description("令牌失效")]
|
||||||
|
TokenInvalidation = 10040,
|
||||||
|
/// <summary>
|
||||||
|
/// 令牌过期
|
||||||
|
/// </summary>
|
||||||
|
TokenExpired = 10050,
|
||||||
|
/// <summary>
|
||||||
|
/// 字段重复
|
||||||
|
/// </summary>
|
||||||
|
RepeatField = 10060,
|
||||||
|
/// <summary>
|
||||||
|
/// 禁止操作
|
||||||
|
/// </summary>
|
||||||
|
Inoperable = 10070,
|
||||||
|
//10080 请求方法不允许
|
||||||
|
|
||||||
|
//10110 文件体积过大
|
||||||
|
|
||||||
|
//10120 文件数量过多
|
||||||
|
|
||||||
|
//10130 文件扩展名不符合规范
|
||||||
|
|
||||||
|
//10140 请求过于频繁,请稍后重试
|
||||||
|
ManyRequests = 10140
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
@@ -6,10 +6,24 @@
|
|||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<DocumentationFile>Knife4jUIDemo.xml</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="IGeekFan.AspNetCore.Knife4jUI" Version="0.0.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.4" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\IGeekFan.AspNetCore.Knife4jUI\IGeekFan.AspNetCore.Knife4jUI.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Knife4jUIDemo.xml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
121
test/Knife4jUIDemo/Knife4jUIDemo.xml
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Knife4jUIDemo</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Knife4jUIDemo.Controllers.WeatherForecastController">
|
||||||
|
<summary>
|
||||||
|
中文这是一个Get请求这是一个Get请求
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Knife4jUIDemo.Controllers.WeatherForecastController.GetErrorCode">
|
||||||
|
<summary>
|
||||||
|
得到一个ErrorCode
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:Knife4jUIDemo.Controllers.WeatherForecastController.PostErrorCode(Knife4jUIDemo.Controllers.PostErrorCodeDto)">
|
||||||
|
<summary>
|
||||||
|
发送一个Post
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:Knife4jUIDemo.Controllers.WeatherForecastController.Get">
|
||||||
|
<summary>
|
||||||
|
这是一个Get请求
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="T:Knife4jUIDemo.Controllers.PostErrorCodeDto">
|
||||||
|
<summary>
|
||||||
|
请求实体
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:Knife4jUIDemo.Controllers.PostErrorCodeDto.Message">
|
||||||
|
<summary>
|
||||||
|
异常信息
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:Knife4jUIDemo.Controllers.PostErrorCodeDto.ErrorCode">
|
||||||
|
<summary>
|
||||||
|
状态码
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:Knife4jUIDemo.ErrorCode">
|
||||||
|
<summary>
|
||||||
|
注释ErrorCode
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.Success">
|
||||||
|
<summary>
|
||||||
|
操作成功
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.UnknownError">
|
||||||
|
<summary>
|
||||||
|
未知错误
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.ServerUnknownError">
|
||||||
|
<summary>
|
||||||
|
服务器未知错误
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.Error">
|
||||||
|
<summary>
|
||||||
|
失败
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.AuthenticationFailed">
|
||||||
|
<summary>
|
||||||
|
认证失败
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.NoPermission">
|
||||||
|
<summary>
|
||||||
|
无权限
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.Fail">
|
||||||
|
<summary>
|
||||||
|
失败
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.RefreshTokenError">
|
||||||
|
<summary>
|
||||||
|
refreshToken异常
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.NotFound">
|
||||||
|
<summary>
|
||||||
|
资源不存在
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.ParameterError">
|
||||||
|
<summary>
|
||||||
|
参数错误
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.TokenInvalidation">
|
||||||
|
<summary>
|
||||||
|
令牌失效
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.TokenExpired">
|
||||||
|
<summary>
|
||||||
|
令牌过期
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.RepeatField">
|
||||||
|
<summary>
|
||||||
|
字段重复
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:Knife4jUIDemo.ErrorCode.Inoperable">
|
||||||
|
<summary>
|
||||||
|
禁止操作
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
},
|
},
|
||||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
"applicationUrl": "http://localhost:5000"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,12 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using IGeekFan.AspNetCore.Knife4jUI;
|
using IGeekFan.AspNetCore.Knife4jUI;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.HttpsPolicy;
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
using System.IO;
|
||||||
|
|
||||||
namespace Knife4jUIDemo
|
namespace Knife4jUIDemo
|
||||||
{
|
{
|
||||||
@@ -40,8 +33,12 @@ namespace Knife4jUIDemo
|
|||||||
});
|
});
|
||||||
c.CustomOperationIds(apiDesc =>
|
c.CustomOperationIds(apiDesc =>
|
||||||
{
|
{
|
||||||
return apiDesc.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : null;
|
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
|
||||||
|
return controllerAction.ControllerName + "-" + controllerAction.ActionName;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var filePath = Path.Combine(System.AppContext.BaseDirectory, "Knife4jUIDemo.xml");
|
||||||
|
c.IncludeXmlComments(filePath, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,16 +58,22 @@ namespace Knife4jUIDemo
|
|||||||
|
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
|
|
||||||
|
app.UseSwaggerUI(c =>
|
||||||
|
{
|
||||||
|
c.SwaggerEndpoint("v1/swagger.json", "My API V1");
|
||||||
|
//c.SwaggerEndpoint("/v1/api-docs", "LinCms");
|
||||||
|
});
|
||||||
|
|
||||||
app.UseKnife4UI(c =>
|
app.UseKnife4UI(c =>
|
||||||
{
|
{
|
||||||
c.RoutePrefix = ""; // serve the UI at root
|
c.RoutePrefix = ""; // serve the UI at root
|
||||||
c.SwaggerEndpoint("/v1/api-docs", "V1 Docs");
|
c.SwaggerEndpoint("/v1/swagger.json", "V1 Docs");
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
endpoints.MapSwagger("{documentName}/api-docs");
|
endpoints.MapSwagger("{documentName}/swagger.json");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NSwag.Swagger.Knife4jUI.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class WeatherForecastController : ControllerBase
|
||||||
|
{
|
||||||
|
private static readonly string[] Summaries = new[]
|
||||||
|
{
|
||||||
|
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly ILogger<WeatherForecastController> _logger;
|
||||||
|
|
||||||
|
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IEnumerable<WeatherForecast> Get()
|
||||||
|
{
|
||||||
|
var rng = new Random();
|
||||||
|
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||||
|
{
|
||||||
|
Date = DateTime.Now.AddDays(index),
|
||||||
|
TemperatureC = rng.Next(-20, 55),
|
||||||
|
Summary = Summaries[rng.Next(Summaries.Length)]
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="NSwag.AspNetCore" Version="13.8.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\IGeekFan.AspNetCore.Knife4jUI\IGeekFan.AspNetCore.Knife4jUI.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
26
test/WebSites/NSwag.Swagger.Knife4jUI/Program.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NSwag.Swagger.Knife4jUI
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
CreateHostBuilder(args).Build().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:2990",
|
||||||
|
"sslPort": 44362
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"NSwag.Swagger.Knife4jUI": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": "true",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
70
test/WebSites/NSwag.Swagger.Knife4jUI/Startup.cs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
using IGeekFan.AspNetCore.Knife4jUI;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.HttpsPolicy;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
// using Microsoft.OpenApi.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NSwag.Swagger.Knife4jUI
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
|
||||||
|
services.AddControllers();
|
||||||
|
services.AddOpenApiDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.UseOpenApi(settings =>
|
||||||
|
{
|
||||||
|
settings.PostProcess = (document, request) =>
|
||||||
|
{
|
||||||
|
document.Info.Title = Configuration["Project:Name"];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
app.UseKnife4UI(c =>
|
||||||
|
{
|
||||||
|
c.RoutePrefix = ""; // serve the UI at root
|
||||||
|
// c.RoutePrefix = "/docs"; // serve the UI at root
|
||||||
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs");
|
||||||
|
});
|
||||||
|
// app.UseSwaggerUi3();
|
||||||
|
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
test/WebSites/NSwag.Swagger.Knife4jUI/WeatherForecast.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NSwag.Swagger.Knife4jUI
|
||||||
|
{
|
||||||
|
public class WeatherForecast
|
||||||
|
{
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureC { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||||
|
|
||||||
|
public string Summary { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
test/WebSites/NSwag.Swagger.Knife4jUI/appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
57
test/WebSites/OAuth2Integration/AuthServer/Config.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using IdentityServer4.Models;
|
||||||
|
using IdentityServer4.Test;
|
||||||
|
|
||||||
|
namespace OAuth2Integration.AuthServer
|
||||||
|
{
|
||||||
|
public static class Config
|
||||||
|
{
|
||||||
|
internal static IEnumerable<Client> Clients()
|
||||||
|
{
|
||||||
|
yield return new Client
|
||||||
|
{
|
||||||
|
ClientId = "test-id",
|
||||||
|
ClientName = "Test client (Code with PKCE)",
|
||||||
|
|
||||||
|
RedirectUris = new[] {
|
||||||
|
"http://localhost:55202/resource-server/swagger/oauth2-redirect.html", // IIS Express
|
||||||
|
"http://localhost:5000/resource-server/swagger/oauth2-redirect.html", // Kestrel
|
||||||
|
},
|
||||||
|
|
||||||
|
ClientSecrets = { new Secret("test-secret".Sha256()) },
|
||||||
|
RequireConsent = true,
|
||||||
|
|
||||||
|
AllowedGrantTypes = GrantTypes.Code,
|
||||||
|
RequirePkce = true,
|
||||||
|
AllowedScopes = new[] { "readAccess", "writeAccess" },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static IEnumerable<ApiResource> ApiResources()
|
||||||
|
{
|
||||||
|
yield return new ApiResource
|
||||||
|
{
|
||||||
|
Name = "api",
|
||||||
|
DisplayName = "API",
|
||||||
|
Scopes = new[]
|
||||||
|
{
|
||||||
|
new Scope("readAccess", "Access read operations"),
|
||||||
|
new Scope("writeAccess", "Access write operations")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static List<TestUser> TestUsers()
|
||||||
|
{
|
||||||
|
return new List<TestUser>
|
||||||
|
{
|
||||||
|
new TestUser
|
||||||
|
{
|
||||||
|
SubjectId = "joebloggs",
|
||||||
|
Username = "joebloggs",
|
||||||
|
Password = "pass123"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using IdentityServer4;
|
||||||
|
using IdentityServer4.Test;
|
||||||
|
using NCaptcha.Abstractions;
|
||||||
|
using NCaptcha.AspNetCore.Extensions;
|
||||||
|
|
||||||
|
namespace OAuth2Integration.AuthServer.Controllers
|
||||||
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
|
[Route("account")]
|
||||||
|
public class AccountController : Controller
|
||||||
|
{
|
||||||
|
private readonly TestUserStore _userStore;
|
||||||
|
|
||||||
|
public AccountController()
|
||||||
|
{
|
||||||
|
_userStore = new TestUserStore(Config.TestUsers());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("login")]
|
||||||
|
public IActionResult Login(string returnUrl)
|
||||||
|
{
|
||||||
|
var viewModel = new LoginViewModel { Username = "joebloggs", Password = "pass123", ReturnUrl = returnUrl };
|
||||||
|
|
||||||
|
return View("/AuthServer/Views/Login.cshtml", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost("login")]
|
||||||
|
public async Task<IActionResult> Login([FromForm] LoginViewModel viewModel)
|
||||||
|
{
|
||||||
|
if (!_userStore.ValidateCredentials(viewModel.Username, viewModel.Password))
|
||||||
|
{
|
||||||
|
ModelState.AddModelError("", "Invalid username or password");
|
||||||
|
viewModel.Password = string.Empty;
|
||||||
|
return View("/AuthServer/Views/Login.cshtml", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use an IdentityServer-compatible ClaimsPrincipal
|
||||||
|
var identityServerUser = new IdentityServerUser(viewModel.Username);
|
||||||
|
identityServerUser.DisplayName = viewModel.Username;
|
||||||
|
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, identityServerUser.CreatePrincipal());
|
||||||
|
|
||||||
|
return Redirect(viewModel.ReturnUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LoginViewModel
|
||||||
|
{
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
public string Username { get; set; }
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using IdentityServer4.Stores;
|
||||||
|
using IdentityServer4.Services;
|
||||||
|
using IdentityServer4.Models;
|
||||||
|
|
||||||
|
namespace OAuth2Integration.AuthServer.Controllers
|
||||||
|
{
|
||||||
|
[ApiExplorerSettings(IgnoreApi = true)]
|
||||||
|
public class ConsentController : Controller
|
||||||
|
{
|
||||||
|
private readonly IIdentityServerInteractionService _interaction;
|
||||||
|
private readonly IClientStore _clientStore;
|
||||||
|
private readonly IResourceStore _resourceStore;
|
||||||
|
|
||||||
|
public ConsentController(
|
||||||
|
IIdentityServerInteractionService interaction,
|
||||||
|
IClientStore clientStore,
|
||||||
|
IResourceStore resourceStore)
|
||||||
|
{
|
||||||
|
_interaction = interaction;
|
||||||
|
_clientStore = clientStore;
|
||||||
|
_resourceStore = resourceStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("consent")]
|
||||||
|
public async Task<IActionResult> Consent(string returnUrl)
|
||||||
|
{
|
||||||
|
var request = await _interaction.GetAuthorizationContextAsync(returnUrl);
|
||||||
|
var client = await _clientStore.FindEnabledClientByIdAsync(request.ClientId);
|
||||||
|
var resource = await _resourceStore.FindApiResourceAsync("api");
|
||||||
|
|
||||||
|
var viewModel = new ConsentViewModel
|
||||||
|
{
|
||||||
|
ReturnUrl = returnUrl,
|
||||||
|
ClientName = client.ClientName,
|
||||||
|
ScopesRequested = resource.Scopes.Where(s => request.ScopesRequested.Contains(s.Name))
|
||||||
|
};
|
||||||
|
|
||||||
|
return View("/AuthServer/Views/Consent.cshtml", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("consent")]
|
||||||
|
public async Task<IActionResult> Consent([FromForm]ConsentViewModel viewModel)
|
||||||
|
{
|
||||||
|
var request = await _interaction.GetAuthorizationContextAsync(viewModel.ReturnUrl);
|
||||||
|
|
||||||
|
// Communicate outcome of consent back to identityserver
|
||||||
|
var consentResponse = new ConsentResponse
|
||||||
|
{
|
||||||
|
ScopesConsented = viewModel.ScopesConsented
|
||||||
|
};
|
||||||
|
await _interaction.GrantConsentAsync(request, consentResponse);
|
||||||
|
|
||||||
|
return Redirect(viewModel.ReturnUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConsentViewModel
|
||||||
|
{
|
||||||
|
public string ReturnUrl { get; set; }
|
||||||
|
public string ClientName { get; set; }
|
||||||
|
public IEnumerable<Scope> ScopesRequested { get; set; }
|
||||||
|
public string[] ScopesConsented { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
@model OAuth2Integration.AuthServer.Controllers.ConsentViewModel
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<h1>Consent</h1>
|
||||||
|
<p>
|
||||||
|
@Model.ClientName is requesting your permission to ...
|
||||||
|
</p>
|
||||||
|
<form asp-controller="Consent" asp-action="Consent">
|
||||||
|
<input type="hidden" asp-for="ReturnUrl" />
|
||||||
|
<fieldset>
|
||||||
|
<ul>
|
||||||
|
@foreach (var scope in Model.ScopesRequested)
|
||||||
|
{
|
||||||
|
<li>
|
||||||
|
<label>
|
||||||
|
<input name="ScopesConsented" type="checkbox" value="@scope.Name" checked />@scope.DisplayName
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</fieldset>
|
||||||
|
<button type="submit">Grant Access</button>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
@model OAuth2Integration.AuthServer.Controllers.LoginViewModel
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<h1>Login</h1>
|
||||||
|
<form asp-controller="Account" asp-action="Login">
|
||||||
|
<input type="hidden" asp-for="ReturnUrl" />
|
||||||
|
<fieldset>
|
||||||
|
<label>
|
||||||
|
Username:
|
||||||
|
<input type="text" asp-for="Username" />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Password:
|
||||||
|
<input type="text" asp-for="Password" />
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
19
test/WebSites/OAuth2Integration/OAuth2Integration.csproj
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="IdentityServer4" Version="3.0.2" />
|
||||||
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
|
||||||
|
<PackageReference Include="NCaptcha.AspNetCore.SessionImages" Version="0.1.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.1.4" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.1.4" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="6.1.4" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\src\IGeekFan.AspNetCore.Knife4jUI\IGeekFan.AspNetCore.Knife4jUI.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
26
test/WebSites/OAuth2Integration/Program.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace OAuth2Integration
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
CreateHostBuilder(args).Build().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:55202",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "resource-server/swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"OAuth2Integration": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "resource-server/swagger",
|
||||||
|
"applicationUrl": "http://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using NCaptcha.Abstractions;
|
||||||
|
using NCaptcha.AspNetCore.Extensions;
|
||||||
|
|
||||||
|
namespace OAuth2Integration.ResourceServer.Controllers
|
||||||
|
{
|
||||||
|
[Route("captcha")]
|
||||||
|
public class CaptchaController : Controller
|
||||||
|
{
|
||||||
|
private readonly ICaptchaGenerator _captchaGenerator;
|
||||||
|
|
||||||
|
public CaptchaController(ICaptchaGenerator captchaGenerator)
|
||||||
|
{
|
||||||
|
_captchaGenerator = captchaGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Produces("image/gif", Type = typeof(FileContentResult))]
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> OnGetCaptchaAsync() => await _captchaGenerator.GetCaptchaFileResultAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
|
namespace OAuth2Integration.ResourceServer.Controllers
|
||||||
|
{
|
||||||
|
[Route("products")]
|
||||||
|
[Authorize(AuthenticationSchemes = "Bearer")]
|
||||||
|
public class ProductsController : Controller
|
||||||
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[Authorize("readAccess")]
|
||||||
|
public IEnumerable<Product> GetProducts()
|
||||||
|
{
|
||||||
|
yield return new Product
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
SerialNo = "ABC123",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
[Authorize("readAccess")]
|
||||||
|
public Product GetProduct(int id)
|
||||||
|
{
|
||||||
|
return new Product
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
SerialNo = "ABC123",
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize("writeAccess")]
|
||||||
|
public void CreateProduct([FromBody]Product product)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
[Authorize("writeAccess")]
|
||||||
|
public void DeleteProduct(int id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Product
|
||||||
|
{
|
||||||
|
public int Id { get; internal set; }
|
||||||
|
public string SerialNo { get; set; }
|
||||||
|
public ProductStatus Status { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ProductStatus
|
||||||
|
{
|
||||||
|
InStock, ComingSoon
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
|
||||||
|
namespace OAuth2Integration.ResourceServer.Swagger
|
||||||
|
{
|
||||||
|
public class SecurityRequirementsOperationFilter : IOperationFilter
|
||||||
|
{
|
||||||
|
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||||
|
{
|
||||||
|
// Policy names map to scopes
|
||||||
|
var requiredScopes = context.MethodInfo
|
||||||
|
.GetCustomAttributes(true)
|
||||||
|
.OfType<AuthorizeAttribute>()
|
||||||
|
.Select(attr => attr.Policy)
|
||||||
|
.Distinct();
|
||||||
|
|
||||||
|
if (requiredScopes.Any())
|
||||||
|
{
|
||||||
|
operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
|
||||||
|
operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });
|
||||||
|
|
||||||
|
var oAuthScheme = new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
|
||||||
|
};
|
||||||
|
|
||||||
|
operation.Security = new List<OpenApiSecurityRequirement>
|
||||||
|
{
|
||||||
|
new OpenApiSecurityRequirement
|
||||||
|
{
|
||||||
|
[ oAuthScheme ] = requiredScopes.ToList()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
172
test/WebSites/OAuth2Integration/Startup.cs
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using NCaptcha.AspNetCore.SessionImages;
|
||||||
|
using IGeekFan.AspNetCore.Knife4jUI;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
|
|
||||||
|
namespace OAuth2Integration
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
// Register IdentityServer services to power OAuth2.0 flows
|
||||||
|
services.AddIdentityServer()
|
||||||
|
.AddDeveloperSigningCredential()
|
||||||
|
.AddInMemoryClients(AuthServer.Config.Clients())
|
||||||
|
.AddInMemoryApiResources(AuthServer.Config.ApiResources())
|
||||||
|
.AddTestUsers(AuthServer.Config.TestUsers());
|
||||||
|
|
||||||
|
// The auth setup is a little nuanced because this app provides the auth-server & the resource-server
|
||||||
|
// Use the "Cookies" scheme by default & explicitly require "Bearer" in the resource-server controllers
|
||||||
|
// See https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?tabs=aspnetcore2x
|
||||||
|
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||||
|
.AddCookie()
|
||||||
|
.AddIdentityServerAuthentication(c =>
|
||||||
|
{
|
||||||
|
c.Authority = "http://localhost:55202/auth-server/";
|
||||||
|
c.RequireHttpsMetadata = false;
|
||||||
|
c.ApiName = "api";
|
||||||
|
});
|
||||||
|
|
||||||
|
// Configure named auth policies that map directly to OAuth2.0 scopes
|
||||||
|
services.AddAuthorization(c =>
|
||||||
|
{
|
||||||
|
c.AddPolicy("readAccess", p => p.RequireClaim("scope", "readAccess"));
|
||||||
|
c.AddPolicy("writeAccess", p => p.RequireClaim("scope", "writeAccess"));
|
||||||
|
});
|
||||||
|
|
||||||
|
services.AddControllersWithViews();
|
||||||
|
|
||||||
|
services.AddSession();
|
||||||
|
services.AddSessionBasedImageCaptcha();
|
||||||
|
|
||||||
|
services.AddSwaggerGen(c =>
|
||||||
|
{
|
||||||
|
c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "Test API V1" });
|
||||||
|
|
||||||
|
// Define the OAuth2.0 scheme that's in use (i.e. Implicit Flow)
|
||||||
|
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Type = SecuritySchemeType.OAuth2,
|
||||||
|
Flows = new OpenApiOAuthFlows
|
||||||
|
{
|
||||||
|
AuthorizationCode = new OpenApiOAuthFlow
|
||||||
|
{
|
||||||
|
AuthorizationUrl = new Uri("/auth-server/connect/authorize", UriKind.Relative),
|
||||||
|
TokenUrl = new Uri("/auth-server/connect/token", UriKind.Relative),
|
||||||
|
Scopes = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "readAccess", "Access read operations" },
|
||||||
|
{ "writeAccess", "Access write operations" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
c.CustomOperationIds(apiDesc =>
|
||||||
|
{
|
||||||
|
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
|
||||||
|
return controllerAction.ControllerName + "-" + controllerAction.ActionName;
|
||||||
|
});
|
||||||
|
|
||||||
|
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
|
||||||
|
},
|
||||||
|
new[] { "readAccess", "writeAccess" }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assign scope requirements to operations based on AuthorizeAttribute
|
||||||
|
//c.OperationFilter<SecurityRequirementsOperationFilter>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseSession();
|
||||||
|
|
||||||
|
app.Map("/auth-server", authServer =>
|
||||||
|
{
|
||||||
|
authServer.UseRouting();
|
||||||
|
|
||||||
|
authServer.UseAuthentication();
|
||||||
|
|
||||||
|
authServer.UseIdentityServer();
|
||||||
|
|
||||||
|
authServer.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Map("/resource-server", resourceServer =>
|
||||||
|
{
|
||||||
|
resourceServer.UseRouting();
|
||||||
|
|
||||||
|
resourceServer.UseAuthentication();
|
||||||
|
|
||||||
|
resourceServer.UseAuthorization();
|
||||||
|
|
||||||
|
resourceServer.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceServer.UseSwagger();
|
||||||
|
|
||||||
|
app.UseKnife4UI(c =>
|
||||||
|
{
|
||||||
|
c.RoutePrefix = ""; //http://localhost:5000/index.html#/home
|
||||||
|
c.SwaggerEndpoint("/resource-server/swagger/v1/swagger.json", "My API V1");
|
||||||
|
c.EnableDeepLinking();
|
||||||
|
c.OAuthClientId("test-id");
|
||||||
|
c.OAuthClientSecret("test-secret");
|
||||||
|
c.OAuthAppName("test-app");
|
||||||
|
c.OAuthScopeSeparator(" ");
|
||||||
|
c.OAuthUsePkce();
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceServer.UseSwaggerUI(c =>
|
||||||
|
{
|
||||||
|
//http://localhost:5000/resource-server/swagger/index.html
|
||||||
|
c.SwaggerEndpoint("/resource-server/swagger/v1/swagger.json", "My API V1");
|
||||||
|
c.EnableDeepLinking();
|
||||||
|
|
||||||
|
// Additional OAuth settings (See https://github.com/swagger-api/swagger-ui/blob/v3.10.0/docs/usage/oauth2.md)
|
||||||
|
c.OAuthClientId("test-id");
|
||||||
|
c.OAuthClientSecret("test-secret");
|
||||||
|
c.OAuthAppName("test-app");
|
||||||
|
c.OAuthScopeSeparator(" ");
|
||||||
|
c.OAuthUsePkce();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Debug",
|
||||||
|
"System": "Information",
|
||||||
|
"Microsoft": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
test/WebSites/OAuth2Integration/appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||