├── .gitattributes ├── .gitignore ├── Publish.SwashbuckleEx.bat ├── Publish.bat ├── README.md ├── Swashbuckle.Core ├── Application │ ├── AreaApiExplorer.cs │ ├── ContactBuilder.cs │ ├── HttpConfigurationExtensions.cs │ ├── HttpRouteDirectionConstraint.cs │ ├── InfoBuilder.cs │ ├── LicenseBuilder.cs │ ├── RedirectHandler.cs │ ├── SecuritySchemeBuilder.cs │ ├── SwaggerDocsConfig.cs │ ├── SwaggerDocsHandler.cs │ ├── SwaggerUiConfig.cs │ ├── SwaggerUiHandler.cs │ ├── VendorExtensionsConverter.cs │ └── VersionInfoBuilder.cs ├── Properties │ └── AssemblyInfo.cs ├── Swagger │ ├── Annotations │ │ ├── ApiAuthorAttribute.cs │ │ ├── ApplySwaggerOperationAttributes.cs │ │ ├── ApplySwaggerOperationFilterAttributes.cs │ │ ├── ApplySwaggerResponseAttributes.cs │ │ ├── ApplySwaggerSchemaFilterAttributes.cs │ │ ├── SwaggerOperationAttribute.cs │ │ ├── SwaggerOperationFilterAttribute.cs │ │ ├── SwaggerResponseAttribute.cs │ │ ├── SwaggerResponseRemoveDefaultsAttribute.cs │ │ └── SwaggerSchemaFilterAttribute.cs │ ├── ApiDescriptionExtensions.cs │ ├── FromUriParams │ │ └── HandleFromUriParams.cs │ ├── IDocumentFilter.cs │ ├── IModelFilter.cs │ ├── IOperationFilter.cs │ ├── ISchemaFilter.cs │ ├── ISwaggerProvider.cs │ ├── JsonContractExtensions.cs │ ├── JsonPropertyExtensions.cs │ ├── SchemaExtensions.cs │ ├── SchemaRegistry.cs │ ├── StringExtensions.cs │ ├── SwaggerDocument.cs │ ├── SwaggerGenerator.cs │ ├── SwaggerGeneratorOptions.cs │ ├── TypeExtensions.cs │ └── XmlComments │ │ ├── ApplyXmlActionComments.cs │ │ ├── ApplyXmlTypeComments.cs │ │ ├── XPathNavigatorExtensions.cs │ │ ├── XmlCommentsIdHelper.cs │ │ └── XmlTextHelper.cs ├── SwaggerUi │ ├── CustomAssets │ │ ├── discoveryUrlSelector.js │ │ ├── index.html │ │ ├── screen.css │ │ └── typography.css │ ├── EmbeddedAssetDescriptor.cs │ ├── EmbeddedAssetProvider.cs │ ├── IAssetProvider.cs │ └── StreamExtensions.cs ├── Swashbuckle.Core.csproj ├── Swashbuckle.Core.nuspec └── packages.config ├── Swashbuckle.WebHost ├── Nuget │ └── Content │ │ └── App_Start │ │ └── SwaggerConfig.cs.pp ├── Properties │ └── AssemblyInfo.cs ├── Swashbuckle.WebHost.csproj └── Swashbuckle.nuspec ├── SwashbuckleEx.WebApiTest ├── App_Start │ ├── SimpleCorsHandler.cs │ ├── SwaggerConfig.cs │ └── WebApiConfig.cs ├── Areas │ ├── Admin │ │ └── Controllers │ │ │ └── TestAController.cs │ ├── Client │ │ └── Controllers │ │ │ └── TestAController.cs │ └── Extensions.cs ├── Controllers │ └── TestAController.cs ├── Extensions │ ├── AddUploadOperationFilter.cs │ └── UploadAttribute.cs ├── Global.asax ├── Global.asax.cs ├── Models │ └── UserInfo.cs ├── Properties │ └── AssemblyInfo.cs ├── Selectors │ ├── AreaHttpControllerSelector.cs │ ├── ClassifiedHttpControllerSelector.cs │ ├── ControllerTypeSpecifications.cs │ ├── NamespaceHttpControllerSelector.cs │ └── SwaggerAreasSupportDocumentFilter.cs ├── Startup.cs ├── SwashbuckleEx.WebApiTest.csproj ├── Web.Debug.config ├── Web.Release.config ├── Web.config └── packages.config ├── SwashbuckleEx.sln ├── swagger-ui ├── css │ ├── ext.css │ ├── print.css │ ├── reset.css │ ├── screen.css │ ├── style.css │ └── typography.css ├── fonts │ ├── DroidSans-Bold.ttf │ └── DroidSans.ttf ├── images │ ├── collapse.gif │ ├── expand.gif │ ├── explorer_icons.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── logo_small.png │ ├── pet_store_api.png │ ├── search.png │ ├── throbber.gif │ └── wordnik_api.png ├── index.html ├── lang │ ├── ca.js │ ├── el.js │ ├── en.js │ ├── es.js │ ├── fr.js │ ├── geo.js │ ├── it.js │ ├── ja.js │ ├── ko-kr.js │ ├── lang.js │ ├── pl.js │ ├── pt.js │ ├── ru.js │ ├── tr.js │ ├── translator.js │ └── zh-cn.js ├── lib │ ├── backbone-min.js │ ├── es5-shim.js │ ├── handlebars-4.0.5.js │ ├── highlight.9.1.0.pack.js │ ├── highlight.9.1.0.pack_extended.js │ ├── jquery-1.8.0.min.js │ ├── jquery.ba-bbq.min.js │ ├── jquery.sieve.js │ ├── jquery.sieve.min.js │ ├── jquery.slideto.min.js │ ├── jquery.wiggle.min.js │ ├── js-yaml.min.js │ ├── jsoneditor.min.js │ ├── lodash.min.js │ ├── marked.js │ ├── object-assign-pollyfill.js │ ├── sanitize-html.min.js │ └── swagger-oauth.js ├── o2c.html ├── sample.json ├── swagger-ui.js └── swagger-ui.min.js └── 新建文本文档.txt /.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 | -------------------------------------------------------------------------------- /.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 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 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 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /Publish.SwashbuckleEx.bat: -------------------------------------------------------------------------------- 1 | set /p key=input key: 2 | call ./Publish.bat "SwashbuckleEx.*.nupkg" "Swashbuckle.WebHost/Swashbuckle.WebHost.csproj" "%key%" 3 | call ./Publish.bat "SwashbuckleEx.Core.*.nupkg" "Swashbuckle.Core/Swashbuckle.Core.csproj" "%key%" 4 | @pause -------------------------------------------------------------------------------- /Publish.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/Publish.bat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/README.md -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/AreaApiExplorer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Web.Http; 10 | using System.Web.Http.Controllers; 11 | using System.Web.Http.Description; 12 | using System.Web.Http.Routing; 13 | 14 | namespace Swashbuckle.Application 15 | { 16 | public class AreaApiExplorer:IApiExplorer 17 | { 18 | private IApiExplorer _innerApiExplorer; 19 | private HttpConfiguration _configuration; 20 | private Lazy> _apiDescriptions; 21 | private MethodInfo _apiDescriptionPopulator; 22 | 23 | public AreaApiExplorer(IApiExplorer apiExplorer, HttpConfiguration configuration) 24 | { 25 | _innerApiExplorer = apiExplorer; 26 | _configuration = configuration; 27 | _apiDescriptions=new Lazy>(new Func>(Init)); 28 | } 29 | 30 | public Collection ApiDescriptions 31 | { 32 | get { return _apiDescriptions.Value; } 33 | } 34 | 35 | private Collection Init() 36 | { 37 | var descriptions = _innerApiExplorer.ApiDescriptions; 38 | var controllerSelector = _configuration.Services.GetHttpControllerSelector(); 39 | var controllerMappings = controllerSelector.GetControllerMapping(); 40 | 41 | var flatRoutes = FlattenRoutes(_configuration.Routes); 42 | var result=new Collection(); 43 | 44 | foreach (var description in descriptions) 45 | { 46 | result.Add(description); 47 | 48 | if (controllerMappings != null) 49 | { 50 | var matchingRoutes = 51 | flatRoutes.Where( 52 | r => r.RouteTemplate == description.Route.RouteTemplate && r != description.Route); 53 | foreach (var route in matchingRoutes) 54 | { 55 | GetRouteDescriptions(route,result); 56 | } 57 | 58 | } 59 | } 60 | return result; 61 | } 62 | 63 | private void GetRouteDescriptions(IHttpRoute route, Collection apiDescriptions) 64 | { 65 | var actionDescriptor = route.DataTokens["actions"] as IEnumerable; 66 | if (actionDescriptor != null && actionDescriptor.Count() > 0) 67 | { 68 | GetPopulateMethod() 69 | .Invoke(_innerApiExplorer, 70 | new object[] {actionDescriptor.First(), route, route.RouteTemplate, apiDescriptions}); 71 | } 72 | } 73 | 74 | private MethodInfo GetPopulateMethod() 75 | { 76 | if (_apiDescriptionPopulator == null) 77 | { 78 | _apiDescriptionPopulator = 79 | _innerApiExplorer.GetType() 80 | .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance) 81 | .FirstOrDefault(m => m.Name == "PopulateActionDescriptions" && m.GetParameters().Length == 4); 82 | } 83 | return _apiDescriptionPopulator; 84 | } 85 | 86 | private static IEnumerable FlattenRoutes(IEnumerable routes) 87 | { 88 | var flatRoutes=new List(); 89 | foreach (var route in routes) 90 | { 91 | if (route is HttpRoute) 92 | { 93 | yield return route; 94 | } 95 | var subRoutes = route as IReadOnlyCollection; 96 | if (subRoutes != null) 97 | { 98 | foreach (var subRoute in FlattenRoutes(subRoutes)) 99 | { 100 | yield return subRoute; 101 | } 102 | } 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/ContactBuilder.cs: -------------------------------------------------------------------------------- 1 | using Swashbuckle.Swagger; 2 | 3 | namespace Swashbuckle.Application 4 | { 5 | public class ContactBuilder 6 | { 7 | private string _name; 8 | private string _url; 9 | private string _email; 10 | 11 | public ContactBuilder Name(string name) 12 | { 13 | _name = name; 14 | return this; 15 | } 16 | 17 | public ContactBuilder Url(string url) 18 | { 19 | _url = url; 20 | return this; 21 | } 22 | 23 | public ContactBuilder Email(string email) 24 | { 25 | _email = email; 26 | return this; 27 | } 28 | 29 | internal Contact Build() 30 | { 31 | if ((_name ?? _url ?? _email) == null) return null; 32 | 33 | return new Contact 34 | { 35 | name = _name, 36 | url = _url, 37 | email = _email 38 | }; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/HttpConfigurationExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Web.Http; 4 | using Newtonsoft.Json.Serialization; 5 | using Swashbuckle.Application; 6 | using System.Net.Http; 7 | using System.Collections.Generic; 8 | using System.Web.Http.Routing; 9 | using Newtonsoft.Json; 10 | 11 | namespace Swashbuckle.Application 12 | { 13 | public static class HttpConfigurationExtensions 14 | { 15 | private static readonly string DefaultRouteTemplate = "swagger/docs/{apiVersion}"; 16 | 17 | public static SwaggerEnabledConfiguration EnableSwagger( 18 | this HttpConfiguration httpConfig, 19 | Action configure = null) 20 | { 21 | return EnableSwagger(httpConfig, DefaultRouteTemplate, configure); 22 | } 23 | 24 | public static SwaggerEnabledConfiguration EnableSwagger( 25 | this HttpConfiguration httpConfig, 26 | string routeTemplate, 27 | Action configure = null) 28 | { 29 | var config = new SwaggerDocsConfig(); 30 | if (configure != null) configure(config); 31 | 32 | httpConfig.Routes.MapHttpRoute( 33 | name: "swagger_docs" + routeTemplate, 34 | routeTemplate: routeTemplate, 35 | defaults: null, 36 | constraints: new { apiVersion = @".+" }, 37 | handler: new SwaggerDocsHandler(config) 38 | ); 39 | 40 | 41 | return new SwaggerEnabledConfiguration( 42 | httpConfig, 43 | config.GetRootUrl, 44 | config.GetApiVersions().Select(version => routeTemplate.Replace("{apiVersion}", version))); 45 | } 46 | 47 | internal static JsonSerializerSettings SerializerSettingsOrDefault(this HttpConfiguration httpConfig) 48 | { 49 | var formatter = httpConfig.Formatters.JsonFormatter; 50 | if (formatter != null) 51 | return formatter.SerializerSettings; 52 | 53 | return new JsonSerializerSettings(); 54 | } 55 | } 56 | 57 | public class SwaggerEnabledConfiguration 58 | { 59 | private static readonly string DefaultRouteTemplate = "swagger/ui/{*assetPath}"; 60 | 61 | private readonly HttpConfiguration _httpConfig; 62 | private readonly Func _rootUrlResolver; 63 | private readonly IEnumerable _discoveryPaths; 64 | 65 | internal static IEnumerable DiscoveryPaths; 66 | 67 | public SwaggerEnabledConfiguration( 68 | HttpConfiguration httpConfig, 69 | Func rootUrlResolver, 70 | IEnumerable discoveryPaths) 71 | { 72 | _httpConfig = httpConfig; 73 | _rootUrlResolver = rootUrlResolver; 74 | _discoveryPaths = discoveryPaths; 75 | DiscoveryPaths = _discoveryPaths; 76 | } 77 | 78 | public void EnableSwaggerUi(Action configure = null) 79 | { 80 | EnableSwaggerUi(DefaultRouteTemplate, configure); 81 | } 82 | 83 | public void EnableSwaggerUi( 84 | string routeTemplate, 85 | Action configure = null) 86 | { 87 | var config = new SwaggerUiConfig(_discoveryPaths, _rootUrlResolver); 88 | if (configure != null) configure(config); 89 | 90 | _httpConfig.Routes.MapHttpRoute( 91 | name: "swagger_ui" + routeTemplate, 92 | routeTemplate: routeTemplate, 93 | defaults: null, 94 | constraints: new { assetPath = @".+" }, 95 | handler: new SwaggerUiHandler(config) 96 | ); 97 | 98 | if (routeTemplate == DefaultRouteTemplate) 99 | { 100 | _httpConfig.Routes.MapHttpRoute( 101 | name: "swagger_ui_shortcut", 102 | routeTemplate: "swagger", 103 | defaults: null, 104 | constraints: new { uriResolution = new HttpRouteDirectionConstraint(HttpRouteDirection.UriResolution) }, 105 | handler: new RedirectHandler(_rootUrlResolver, "swagger/ui/index")); 106 | } 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/HttpRouteDirectionConstraint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Text; 6 | using System.Web.Http.Routing; 7 | 8 | namespace Swashbuckle.Application 9 | { 10 | public class HttpRouteDirectionConstraint : IHttpRouteConstraint 11 | { 12 | private readonly HttpRouteDirection _allowedDirection; 13 | 14 | public HttpRouteDirectionConstraint(HttpRouteDirection allowedDirection) 15 | { 16 | _allowedDirection = allowedDirection; 17 | } 18 | 19 | public bool Match( 20 | HttpRequestMessage request, 21 | IHttpRoute route, 22 | string parameterName, 23 | IDictionary values, 24 | HttpRouteDirection routeDirection) 25 | { 26 | return routeDirection == _allowedDirection; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/InfoBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Swashbuckle.Swagger; 3 | 4 | namespace Swashbuckle.Application 5 | { 6 | public class InfoBuilder 7 | { 8 | private string _version; 9 | private string _title; 10 | private string _description; 11 | private string _termsOfService; 12 | /// 13 | /// 是否默认路由 14 | /// 15 | private bool _isDefaultRoute; 16 | private readonly ContactBuilder _contactBuilder = new ContactBuilder(); 17 | private readonly LicenseBuilder _licenseBuilder = new LicenseBuilder(); 18 | 19 | public InfoBuilder(string version, string title) 20 | { 21 | _version = version; 22 | _title = title; 23 | } 24 | 25 | public InfoBuilder(string version, string title, bool isDefualt):this(version,title) 26 | { 27 | _isDefaultRoute = isDefualt; 28 | } 29 | 30 | public InfoBuilder Description(string description) 31 | { 32 | _description = description; 33 | return this; 34 | } 35 | 36 | public InfoBuilder TermsOfService(string termsOfService) 37 | { 38 | _termsOfService = termsOfService; 39 | return this; 40 | } 41 | 42 | public InfoBuilder Contact(Action contact) 43 | { 44 | contact(_contactBuilder); 45 | return this; 46 | } 47 | 48 | public InfoBuilder License(Action license) 49 | { 50 | license(_licenseBuilder); 51 | return this; 52 | } 53 | 54 | internal Info Build() 55 | { 56 | return new Info 57 | { 58 | version = _version, 59 | title = _title, 60 | description = _description, 61 | termsOfService = _termsOfService, 62 | contact = _contactBuilder.Build(), 63 | license = _licenseBuilder.Build(), 64 | isDefaultRoute = _isDefaultRoute 65 | }; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/LicenseBuilder.cs: -------------------------------------------------------------------------------- 1 | using Swashbuckle.Swagger; 2 | 3 | namespace Swashbuckle.Application 4 | { 5 | public class LicenseBuilder 6 | { 7 | private string _name; 8 | private string _url; 9 | 10 | public LicenseBuilder Name(string name) 11 | { 12 | _name = name; 13 | return this; 14 | } 15 | 16 | public LicenseBuilder Url(string url) 17 | { 18 | _url = url; 19 | return this; 20 | } 21 | 22 | internal License Build() 23 | { 24 | if ((_name ?? _url) == null) return null; 25 | 26 | return new License 27 | { 28 | name = _name, 29 | url = _url 30 | }; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/RedirectHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Http; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Swashbuckle.Application 8 | { 9 | public class RedirectHandler : HttpMessageHandler 10 | { 11 | private readonly Func _rootUrlResolver; 12 | private readonly string _redirectPath; 13 | 14 | public RedirectHandler(Func rootUrlResolver, string redirectPath) 15 | { 16 | _rootUrlResolver = rootUrlResolver; 17 | _redirectPath = redirectPath; 18 | } 19 | 20 | protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 21 | { 22 | var redirectUrl = _rootUrlResolver(request) + "/" + _redirectPath; 23 | 24 | var response = request.CreateResponse(HttpStatusCode.Moved); 25 | response.Headers.Location = new Uri(redirectUrl); 26 | 27 | var tsc = new TaskCompletionSource(); 28 | tsc.SetResult(response); 29 | return tsc.Task; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/SecuritySchemeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Swashbuckle.Swagger; 5 | 6 | namespace Swashbuckle.Application 7 | { 8 | public abstract class SecuritySchemeBuilder 9 | { 10 | internal abstract SecurityScheme Build(); 11 | } 12 | 13 | public class BasicAuthSchemeBuilder : SecuritySchemeBuilder 14 | { 15 | private string _description; 16 | 17 | public BasicAuthSchemeBuilder Description(string description) 18 | { 19 | _description = description; 20 | return this; 21 | } 22 | 23 | internal override SecurityScheme Build() 24 | { 25 | return new SecurityScheme 26 | { 27 | type = "basic", 28 | description = _description 29 | }; 30 | } 31 | } 32 | 33 | public class ApiKeySchemeBuilder : SecuritySchemeBuilder 34 | { 35 | private string _description; 36 | private string _name; 37 | private string _in; 38 | 39 | public ApiKeySchemeBuilder Description(string description) 40 | { 41 | _description = description; 42 | return this; 43 | } 44 | 45 | public ApiKeySchemeBuilder Name(string name) 46 | { 47 | _name = name; 48 | return this; 49 | } 50 | 51 | public ApiKeySchemeBuilder In(string @in) 52 | { 53 | _in = @in; 54 | return this; 55 | } 56 | 57 | internal override SecurityScheme Build() 58 | { 59 | return new SecurityScheme 60 | { 61 | type = "apiKey", 62 | description = _description, 63 | name = _name, 64 | @in = _in 65 | }; 66 | } 67 | } 68 | 69 | public class OAuth2SchemeBuilder : SecuritySchemeBuilder 70 | { 71 | private string _description; 72 | private string _flow; 73 | private string _authorizationUrl; 74 | private string _tokenUrl; 75 | private IDictionary _scopes = new Dictionary(); 76 | 77 | public OAuth2SchemeBuilder Description(string description) 78 | { 79 | _description = description; 80 | return this; 81 | } 82 | 83 | public OAuth2SchemeBuilder Flow(string flow) 84 | { 85 | _flow = flow; 86 | return this; 87 | } 88 | 89 | public OAuth2SchemeBuilder AuthorizationUrl(string authorizationUrl) 90 | { 91 | _authorizationUrl = authorizationUrl; 92 | return this; 93 | } 94 | 95 | public OAuth2SchemeBuilder TokenUrl(string tokenUrl) 96 | { 97 | _tokenUrl = tokenUrl; 98 | return this; 99 | } 100 | 101 | public OAuth2SchemeBuilder Scopes(Action> configure) 102 | { 103 | configure(_scopes); 104 | return this; 105 | } 106 | 107 | internal override SecurityScheme Build() 108 | { 109 | // TODO: Validate required fields for given flow 110 | 111 | return new SecurityScheme 112 | { 113 | type = "oauth2", 114 | flow = _flow, 115 | authorizationUrl = _authorizationUrl, 116 | tokenUrl = _tokenUrl, 117 | scopes = _scopes, 118 | description = _description, 119 | }; 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/SwaggerDocsHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Http; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using System.Web.Http; 6 | using System.Net.Http.Formatting; 7 | using Newtonsoft.Json; 8 | using Newtonsoft.Json.Serialization; 9 | using System.Collections.Generic; 10 | using Swashbuckle.Swagger; 11 | using System.Net; 12 | 13 | namespace Swashbuckle.Application 14 | { 15 | public class SwaggerDocsHandler : HttpMessageHandler 16 | { 17 | private readonly SwaggerDocsConfig _config; 18 | 19 | public SwaggerDocsHandler(SwaggerDocsConfig config) 20 | { 21 | _config = config; 22 | } 23 | 24 | protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 25 | { 26 | var swaggerProvider = _config.GetSwaggerProvider(request); 27 | var rootUrl = _config.GetRootUrl(request); 28 | var apiVersion = request.GetRouteData().Values["apiVersion"].ToString(); 29 | 30 | try 31 | { 32 | var swaggerDoc = swaggerProvider.GetSwagger(rootUrl, apiVersion); 33 | var content = ContentFor(request, swaggerDoc); 34 | return TaskFor(new HttpResponseMessage { Content = content }); 35 | } 36 | catch (UnknownApiVersion ex) 37 | { 38 | return TaskFor(request.CreateErrorResponse(HttpStatusCode.NotFound, ex)); 39 | } 40 | } 41 | 42 | private HttpContent ContentFor(HttpRequestMessage request, SwaggerDocument swaggerDoc) 43 | { 44 | var negotiator = request.GetConfiguration().Services.GetContentNegotiator(); 45 | var result = negotiator.Negotiate(typeof(SwaggerDocument), request, GetSupportedSwaggerFormatters()); 46 | 47 | return new ObjectContent(typeof(SwaggerDocument), swaggerDoc, result.Formatter, result.MediaType); 48 | } 49 | 50 | private IEnumerable GetSupportedSwaggerFormatters() 51 | { 52 | var jsonFormatter = new JsonMediaTypeFormatter 53 | { 54 | SerializerSettings = new JsonSerializerSettings 55 | { 56 | NullValueHandling = NullValueHandling.Ignore, 57 | Formatting = _config.GetFormatting(), 58 | Converters = new[] { new VendorExtensionsConverter() } 59 | } 60 | }; 61 | // NOTE: The custom converter would not be neccessary in Newtonsoft.Json >= 5.0.5 as JsonExtensionData 62 | // provides similar functionality. But, need to stick with older version for WebApi 5.0.0 compatibility 63 | return new[] { jsonFormatter }; 64 | } 65 | 66 | private Task TaskFor(HttpResponseMessage response) 67 | { 68 | var tsc = new TaskCompletionSource(); 69 | tsc.SetResult(response); 70 | return tsc.Task; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/SwaggerUiHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System.Threading; 3 | using System; 4 | using System.Threading.Tasks; 5 | using System.Net; 6 | using System.Net.Http.Headers; 7 | using Swashbuckle.SwaggerUi; 8 | 9 | namespace Swashbuckle.Application 10 | { 11 | public class SwaggerUiHandler : HttpMessageHandler 12 | { 13 | private readonly SwaggerUiConfig _config; 14 | 15 | public SwaggerUiHandler(SwaggerUiConfig config) 16 | { 17 | _config = config; 18 | } 19 | 20 | protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 21 | { 22 | var swaggerUiProvider = _config.GetSwaggerUiProvider(); 23 | var rootUrl = _config.GetRootUrl(request); 24 | var assetPath = request.GetRouteData().Values["assetPath"].ToString(); 25 | 26 | try 27 | { 28 | var webAsset = swaggerUiProvider.GetAsset(rootUrl, assetPath); 29 | var content = ContentFor(webAsset); 30 | return TaskFor(new HttpResponseMessage { Content = content }); 31 | } 32 | catch (AssetNotFound ex) 33 | { 34 | return TaskFor(request.CreateErrorResponse(HttpStatusCode.NotFound, ex)); 35 | } 36 | } 37 | 38 | private HttpContent ContentFor(Asset webAsset) 39 | { 40 | int bufferSize = webAsset.Stream.Length > int.MaxValue 41 | ? int.MaxValue 42 | : (int)webAsset.Stream.Length; 43 | 44 | var content = new StreamContent(webAsset.Stream, bufferSize); 45 | content.Headers.ContentType = new MediaTypeHeaderValue(webAsset.MediaType); 46 | return content; 47 | } 48 | 49 | private Task TaskFor(HttpResponseMessage response) 50 | { 51 | var tsc = new TaskCompletionSource(); 52 | tsc.SetResult(response); 53 | return tsc.Task; 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/VendorExtensionsConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using Newtonsoft.Json; 6 | using Newtonsoft.Json.Serialization; 7 | using Swashbuckle.Swagger; 8 | 9 | namespace Swashbuckle.Application 10 | { 11 | public class VendorExtensionsConverter : JsonConverter 12 | { 13 | public override bool CanConvert(Type objectType) 14 | { 15 | return objectType.GetField("vendorExtensions") != null; 16 | } 17 | 18 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 19 | { 20 | throw new NotImplementedException(); 21 | } 22 | 23 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 24 | { 25 | var jsonContract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType()); 26 | 27 | writer.WriteStartObject(); 28 | 29 | foreach (var jsonProp in jsonContract.Properties) 30 | { 31 | var propValue = jsonProp.ValueProvider.GetValue(value); 32 | if (propValue == null && serializer.NullValueHandling == NullValueHandling.Ignore) 33 | continue; 34 | 35 | if (jsonProp.PropertyName == "vendorExtensions") 36 | { 37 | var vendorExtensions = (IDictionary)propValue; 38 | if (vendorExtensions.Any()) 39 | { 40 | foreach (var entry in vendorExtensions) 41 | { 42 | writer.WritePropertyName(entry.Key); 43 | serializer.Serialize(writer, entry.Value); 44 | } 45 | } 46 | } 47 | else 48 | { 49 | writer.WritePropertyName(jsonProp.PropertyName); 50 | serializer.Serialize(writer, propValue); 51 | } 52 | } 53 | 54 | writer.WriteEndObject(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Application/VersionInfoBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Swashbuckle.Swagger; 5 | 6 | namespace Swashbuckle.Application 7 | { 8 | public class VersionInfoBuilder 9 | { 10 | private readonly Dictionary _versionInfos; 11 | 12 | public VersionInfoBuilder() 13 | { 14 | _versionInfos = new Dictionary(); 15 | } 16 | 17 | public InfoBuilder Version(string version, string title) 18 | { 19 | var infoBuilder = new InfoBuilder(version, title); 20 | _versionInfos[version] = infoBuilder; 21 | return infoBuilder; 22 | } 23 | 24 | public InfoBuilder Version(string version, string title, bool isDefaultRoute) 25 | { 26 | var infoBuilder = new InfoBuilder(version, title, isDefaultRoute); 27 | _versionInfos[version] = infoBuilder; 28 | return infoBuilder; 29 | } 30 | 31 | public IDictionary Build() 32 | { 33 | return _versionInfos.ToDictionary(entry => entry.Key, entry => entry.Value.Build()); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Swashbuckle.Core")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Swashbuckle.Core")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("15e76579-e0c4-4cd4-9083-0e04f9fd531d")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.3.0")] 36 | [assembly: AssemblyFileVersion("1.1.3.0")] 37 | [assembly: AssemblyInformationalVersion("1.1.3.0")] 38 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/ApiAuthorAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Swashbuckle.Swagger.Annotations 8 | { 9 | /// 10 | /// Api作者信息 11 | /// 12 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 13 | public class ApiAuthorAttribute:Attribute 14 | { 15 | /// 16 | /// 名称 17 | /// 18 | public string Name { get; set; } 19 | 20 | /// 21 | /// 更新时间 22 | /// 23 | public string Time { get; set; } 24 | 25 | /// 26 | /// 开发状态 27 | /// 28 | public DevStatus Status { get; set; } = DevStatus.None; 29 | 30 | /// 31 | /// 获取开发状态名 32 | /// 33 | /// 34 | public string GetStatusName() 35 | { 36 | switch (Status) 37 | { 38 | case DevStatus.Wait: 39 | return "等待开发"; 40 | case DevStatus.Dev: 41 | return "开发中"; 42 | case DevStatus.Finish: 43 | return "开发完成"; 44 | case DevStatus.None: 45 | return "不显示"; 46 | default: 47 | return string.Empty; 48 | } 49 | } 50 | } 51 | 52 | /// 53 | /// 开发状态 54 | /// 55 | public enum DevStatus 56 | { 57 | /// 58 | /// 无 59 | /// 60 | None, 61 | /// 62 | /// 等待开发 63 | /// 64 | Wait, 65 | /// 66 | /// 开发中 67 | /// 68 | Dev, 69 | /// 70 | /// 开发完成 71 | /// 72 | Finish 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/ApplySwaggerOperationAttributes.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web.Http.Description; 3 | 4 | namespace Swashbuckle.Swagger.Annotations 5 | { 6 | public class ApplySwaggerOperationAttributes : IOperationFilter 7 | { 8 | public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) 9 | { 10 | var attribute = apiDescription.ActionDescriptor.GetCustomAttributes() 11 | .FirstOrDefault(); 12 | if (attribute == null) return; 13 | 14 | if (attribute.OperationId != null) 15 | operation.operationId = attribute.OperationId; 16 | 17 | if (attribute.Tags != null) 18 | operation.tags = attribute.Tags; 19 | 20 | if (attribute.Schemes != null) 21 | operation.schemes = attribute.Schemes; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/ApplySwaggerOperationFilterAttributes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Http.Description; 3 | 4 | namespace Swashbuckle.Swagger.Annotations 5 | { 6 | public class ApplySwaggerOperationFilterAttributes : IOperationFilter 7 | { 8 | public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) 9 | { 10 | var attributes = apiDescription.GetControllerAndActionAttributes(); 11 | 12 | foreach (var attribute in attributes) 13 | { 14 | var filter = (IOperationFilter)Activator.CreateInstance(attribute.FilterType); 15 | filter.Apply(operation, schemaRegistry, apiDescription); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/ApplySwaggerResponseAttributes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Web.Http.Description; 6 | 7 | namespace Swashbuckle.Swagger.Annotations 8 | { 9 | public class ApplySwaggerResponseAttributes : IOperationFilter 10 | { 11 | public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) 12 | { 13 | if (apiDescription.GetControllerAndActionAttributes().Any()) 14 | operation.responses.Clear(); 15 | 16 | var responseAttributes = apiDescription.GetControllerAndActionAttributes() 17 | .OrderBy(attr => attr.StatusCode); 18 | 19 | foreach (var attr in responseAttributes) 20 | { 21 | var statusCode = attr.StatusCode.ToString(); 22 | 23 | operation.responses[statusCode] = new Response 24 | { 25 | description = attr.Description ?? InferDescriptionFrom(statusCode), 26 | schema = (attr.Type != null) ? schemaRegistry.GetOrRegister(attr.Type) : null 27 | }; 28 | } 29 | } 30 | 31 | private string InferDescriptionFrom(string statusCode) 32 | { 33 | HttpStatusCode enumValue; 34 | if (Enum.TryParse(statusCode, true, out enumValue)) 35 | { 36 | return enumValue.ToString(); 37 | } 38 | return null; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/ApplySwaggerSchemaFilterAttributes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Web.Http.Description; 4 | 5 | namespace Swashbuckle.Swagger.Annotations 6 | { 7 | public class ApplySwaggerSchemaFilterAttributes : ISchemaFilter 8 | { 9 | public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) 10 | { 11 | var attributes = type.GetCustomAttributes(false).OfType(); 12 | 13 | foreach (var attribute in attributes) 14 | { 15 | var filter = (ISchemaFilter)Activator.CreateInstance(attribute.FilterType); 16 | filter.Apply(schema, schemaRegistry, type); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/SwaggerOperationAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Swashbuckle.Swagger.Annotations 5 | { 6 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 7 | public class SwaggerOperationAttribute : Attribute 8 | { 9 | public SwaggerOperationAttribute(string operationId = null) 10 | { 11 | OperationId = operationId; 12 | } 13 | 14 | public string OperationId { get; set; } 15 | 16 | public string[] Tags { get; set; } 17 | 18 | public string[] Schemes { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/SwaggerOperationFilterAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Swashbuckle.Swagger.Annotations 4 | { 5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] 6 | public class SwaggerOperationFilterAttribute : Attribute 7 | { 8 | public SwaggerOperationFilterAttribute(Type filterType) 9 | { 10 | FilterType = filterType; 11 | } 12 | 13 | public Type FilterType { get; private set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/SwaggerResponseAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace Swashbuckle.Swagger.Annotations 5 | { 6 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] 7 | public class SwaggerResponseAttribute : Attribute 8 | { 9 | public SwaggerResponseAttribute(HttpStatusCode statusCode) 10 | { 11 | StatusCode = (int)statusCode; 12 | } 13 | 14 | public SwaggerResponseAttribute(HttpStatusCode statusCode, string description = null, Type type = null) 15 | : this(statusCode) 16 | { 17 | Description = description; 18 | Type = type; 19 | } 20 | 21 | public SwaggerResponseAttribute(int statusCode) 22 | { 23 | StatusCode = statusCode; 24 | } 25 | 26 | public SwaggerResponseAttribute(int statusCode, string description = null, Type type = null) 27 | : this(statusCode) 28 | { 29 | Description = description; 30 | Type = type; 31 | } 32 | 33 | public int StatusCode { get; private set; } 34 | 35 | public string Description { get; set; } 36 | 37 | public Type Type { get; set; } 38 | } 39 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/SwaggerResponseRemoveDefaultsAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace Swashbuckle.Swagger.Annotations 5 | { 6 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] 7 | public class SwaggerResponseRemoveDefaultsAttribute : Attribute 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/Annotations/SwaggerSchemaFilterAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Swashbuckle.Swagger.Annotations 4 | { 5 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 6 | public class SwaggerSchemaFilterAttribute : Attribute 7 | { 8 | public SwaggerSchemaFilterAttribute(Type filterType) 9 | { 10 | FilterType = filterType; 11 | } 12 | 13 | public Type FilterType { get; private set; } 14 | } 15 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/ApiDescriptionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | using System.Web.Http.Description; 5 | 6 | namespace Swashbuckle.Swagger 7 | { 8 | public static class ApiDescriptionExtensions 9 | { 10 | public static string FriendlyId(this ApiDescription apiDescription) 11 | { 12 | return String.Format("{0}_{1}", 13 | apiDescription.ActionDescriptor.ControllerDescriptor.ControllerName, 14 | apiDescription.ActionDescriptor.ActionName); 15 | } 16 | 17 | public static IEnumerable Consumes(this ApiDescription apiDescription) 18 | { 19 | return apiDescription.SupportedRequestBodyFormatters 20 | .SelectMany(formatter => formatter.SupportedMediaTypes.Select(mediaType => mediaType.MediaType)) 21 | .Distinct(); 22 | } 23 | 24 | public static IEnumerable Produces(this ApiDescription apiDescription) 25 | { 26 | return apiDescription.SupportedResponseFormatters 27 | .SelectMany(formatter => formatter.SupportedMediaTypes.Select(mediaType => mediaType.MediaType)) 28 | .Distinct(); 29 | } 30 | 31 | public static string RelativePathSansQueryString(this ApiDescription apiDescription) 32 | { 33 | return apiDescription.RelativePath.Split('?').First(); 34 | } 35 | 36 | public static Type ResponseType(this ApiDescription apiDesc) 37 | { 38 | // HACK: The ResponseDescription property was introduced in WebApi 5.0 but Swashbuckle supports >= 4.0. 39 | // The reflection hack below provides support for the ResponseType attribute if the application is running 40 | // against a version of WebApi that supports it. 41 | var apiDescType = typeof(ApiDescription); 42 | 43 | var responseDescPropInfo = apiDescType.GetProperty("ResponseDescription"); 44 | if (responseDescPropInfo != null) 45 | { 46 | var responseDesc = responseDescPropInfo.GetValue(apiDesc, null); 47 | if (responseDesc != null) 48 | { 49 | var responseDescType = responseDesc.GetType(); 50 | 51 | var responseTypePropInfo = responseDescType.GetProperty("ResponseType"); 52 | if (responseTypePropInfo != null) 53 | { 54 | var responseType = responseTypePropInfo.GetValue(responseDesc, null); 55 | if (responseType != null) 56 | return (Type)responseType; 57 | } 58 | } 59 | } 60 | 61 | // Otherwise, it defaults to the declared response type 62 | return apiDesc.ActionDescriptor.ReturnType; 63 | } 64 | 65 | public static bool IsObsolete(this ApiDescription apiDescription) 66 | { 67 | return apiDescription.ActionDescriptor.GetCustomAttributes().Any(); 68 | } 69 | 70 | public static IEnumerable GetControllerAndActionAttributes(this ApiDescription apiDesc) 71 | where TAttribute : class 72 | { 73 | var controllerAttributes = apiDesc.ActionDescriptor.ControllerDescriptor 74 | .GetCustomAttributes(); 75 | 76 | var actionAttributes = apiDesc.ActionDescriptor 77 | .GetCustomAttributes(); 78 | 79 | return controllerAttributes.Concat(actionAttributes); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/FromUriParams/HandleFromUriParams.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web.Http.Description; 3 | using Swashbuckle.Swagger; 4 | using System.Collections.Generic; 5 | 6 | namespace Swashbuckle.Swagger.FromUriParams 7 | { 8 | public class HandleFromUriParams : IOperationFilter 9 | { 10 | public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) 11 | { 12 | if (operation.parameters == null) return; 13 | 14 | HandleFromUriArrayParams(operation); 15 | HandleFromUriObjectParams(operation, schemaRegistry, apiDescription); 16 | } 17 | 18 | private static void HandleFromUriArrayParams(Operation operation) 19 | { 20 | var fromUriArrayParams = operation.parameters 21 | .Where(param => param.@in == "query" && param.type == "array") 22 | .ToArray(); 23 | 24 | foreach (var param in fromUriArrayParams) 25 | { 26 | param.collectionFormat = "multi"; 27 | } 28 | } 29 | 30 | private void HandleFromUriObjectParams(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) 31 | { 32 | var fromUriObjectParams = operation.parameters 33 | .Where(param => param.@in == "query" && param.type == null) 34 | .ToArray(); 35 | 36 | foreach (var objectParam in fromUriObjectParams) 37 | { 38 | var type = apiDescription.ParameterDescriptions 39 | .Single(paramDesc => paramDesc.Name == objectParam.name) 40 | .ParameterDescriptor.ParameterType; 41 | 42 | var refSchema = schemaRegistry.GetOrRegister(type); 43 | var schema = schemaRegistry.Definitions[refSchema.@ref.Replace("#/definitions/", "")]; 44 | 45 | var qualifier = string.IsNullOrEmpty(objectParam.name) ? "" : (objectParam.name + "."); 46 | ExtractAndAddQueryParams(schema, qualifier, objectParam.required, schemaRegistry, operation.parameters); 47 | operation.parameters.Remove(objectParam); 48 | } 49 | } 50 | 51 | private void ExtractAndAddQueryParams( 52 | Schema sourceSchema, 53 | string sourceQualifier, 54 | bool? sourceRequired, 55 | SchemaRegistry schemaRegistry, 56 | IList operationParams) 57 | { 58 | foreach (var entry in sourceSchema.properties) 59 | { 60 | var propertySchema = entry.Value; 61 | if (propertySchema.readOnly == true) continue; 62 | 63 | var required = (sourceRequired == true) 64 | && sourceSchema.required != null && sourceSchema.required.Contains(entry.Key); 65 | 66 | if (propertySchema.@ref != null) 67 | { 68 | var schema = schemaRegistry.Definitions[propertySchema.@ref.Replace("#/definitions/", "")]; 69 | ExtractAndAddQueryParams( 70 | schema, 71 | sourceQualifier + entry.Key.ToCamelCase() + ".", 72 | required, 73 | schemaRegistry, 74 | operationParams); 75 | } 76 | else 77 | { 78 | var param = new Parameter 79 | { 80 | name = sourceQualifier + entry.Key.ToCamelCase(), 81 | @in = "query", 82 | required = required, 83 | description = entry.Value.description 84 | }; 85 | param.PopulateFrom(entry.Value); 86 | if (param.type == "array") 87 | param.collectionFormat = "multi"; 88 | operationParams.Add(param); 89 | } 90 | } 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/IDocumentFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Http.Description; 2 | 3 | namespace Swashbuckle.Swagger 4 | { 5 | public interface IDocumentFilter 6 | { 7 | void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/IModelFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.XPath; 3 | using Newtonsoft.Json.Serialization; 4 | 5 | namespace Swashbuckle.Swagger 6 | { 7 | public interface IModelFilter 8 | { 9 | XPathNavigator XmlNavigator { get; } 10 | void Apply(Schema model, ModelFilterContext context); 11 | } 12 | 13 | public class ModelFilterContext 14 | { 15 | public ModelFilterContext( 16 | Type systemType, 17 | JsonObjectContract jsonObjectContract, 18 | SchemaRegistry schemaRegistry) 19 | { 20 | SystemType = systemType; 21 | JsonObjectContract = jsonObjectContract; 22 | SchemaRegistry = schemaRegistry; 23 | } 24 | 25 | public Type SystemType { get; private set; } 26 | 27 | public JsonObjectContract JsonObjectContract { get; private set; } 28 | 29 | public SchemaRegistry SchemaRegistry { get; private set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/IOperationFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Http.Description; 2 | 3 | namespace Swashbuckle.Swagger 4 | { 5 | public interface IOperationFilter 6 | { 7 | void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/ISchemaFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Swashbuckle.Swagger 4 | { 5 | public interface ISchemaFilter 6 | { 7 | void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type); 8 | } 9 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/ISwaggerProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Swashbuckle.Swagger 4 | { 5 | public interface ISwaggerProvider 6 | { 7 | SwaggerDocument GetSwagger(string rootUrl, string apiVersion); 8 | } 9 | 10 | public class UnknownApiVersion : Exception 11 | { 12 | public UnknownApiVersion(string apiVersion) 13 | : base(String.Format("Unknown API version - {0}", apiVersion)) 14 | {} 15 | } 16 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/JsonContractExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Serialization; 5 | 6 | namespace Swashbuckle.Swagger 7 | { 8 | public static class JsonContractExtensions 9 | { 10 | private static IEnumerable AmbiguousTypeNames = new[] 11 | { 12 | "System.Object", 13 | "System.Net.Http.HttpRequestMessage", 14 | "System.Net.Http.HttpResponseMessage", 15 | "System.Web.Http.IHttpActionResult" 16 | }; 17 | 18 | public static bool IsSelfReferencing(this JsonDictionaryContract dictionaryContract) 19 | { 20 | return dictionaryContract.UnderlyingType == dictionaryContract.DictionaryValueType; 21 | } 22 | 23 | public static bool IsSelfReferencing(this JsonArrayContract arrayContract) 24 | { 25 | return arrayContract.UnderlyingType == arrayContract.CollectionItemType; 26 | } 27 | 28 | public static bool IsAmbiguous(this JsonObjectContract objectContract) 29 | { 30 | return AmbiguousTypeNames.Contains(objectContract.UnderlyingType.FullName); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/JsonPropertyExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.Linq; 4 | using System.Reflection; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | namespace Swashbuckle.Swagger 8 | { 9 | public static class JsonPropertyExtensions 10 | { 11 | public static bool IsRequired(this JsonProperty jsonProperty) 12 | { 13 | return jsonProperty.HasAttribute(); 14 | } 15 | 16 | public static bool IsObsolete(this JsonProperty jsonProperty) 17 | { 18 | return jsonProperty.HasAttribute(); 19 | } 20 | 21 | public static bool HasAttribute(this JsonProperty jsonProperty) 22 | { 23 | var propInfo = jsonProperty.PropertyInfo(); 24 | return propInfo != null && Attribute.IsDefined(propInfo, typeof (T)); 25 | } 26 | 27 | public static PropertyInfo PropertyInfo(this JsonProperty jsonProperty) 28 | { 29 | if (jsonProperty.UnderlyingName == null) return null; 30 | 31 | var metadata = jsonProperty.DeclaringType.GetCustomAttributes(typeof(MetadataTypeAttribute), true) 32 | .FirstOrDefault(); 33 | 34 | var typeToReflect = (metadata != null) 35 | ? ((MetadataTypeAttribute)metadata).MetadataClassType 36 | : jsonProperty.DeclaringType; 37 | 38 | return typeToReflect.GetProperty(jsonProperty.UnderlyingName, jsonProperty.PropertyType); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/SchemaExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | using System.ComponentModel.DataAnnotations; 5 | using Newtonsoft.Json.Serialization; 6 | 7 | namespace Swashbuckle.Swagger 8 | { 9 | public static class SchemaExtensions 10 | { 11 | public static Schema WithValidationProperties(this Schema schema, JsonProperty jsonProperty) 12 | { 13 | var propInfo = jsonProperty.PropertyInfo(); 14 | if (propInfo == null) 15 | return schema; 16 | 17 | foreach (var attribute in propInfo.GetCustomAttributes(false)) 18 | { 19 | var regex = attribute as RegularExpressionAttribute; 20 | if (regex != null) 21 | schema.pattern = regex.Pattern; 22 | 23 | var range = attribute as RangeAttribute; 24 | if (range != null) 25 | { 26 | int maximum; 27 | if (Int32.TryParse(range.Maximum.ToString(), out maximum)) 28 | schema.maximum = maximum; 29 | 30 | int minimum; 31 | if (Int32.TryParse(range.Minimum.ToString(), out minimum)) 32 | schema.minimum = minimum; 33 | } 34 | 35 | var length = attribute as StringLengthAttribute; 36 | if (length != null) 37 | { 38 | schema.maxLength = length.MaximumLength; 39 | schema.minLength = length.MinimumLength; 40 | } 41 | } 42 | 43 | if (!jsonProperty.Writable) 44 | schema.readOnly = true; 45 | 46 | return schema; 47 | } 48 | 49 | public static void PopulateFrom(this PartialSchema partialSchema, Schema schema) 50 | { 51 | if (schema == null) return; 52 | 53 | partialSchema.type = schema.type; 54 | partialSchema.format = schema.format; 55 | partialSchema.vendorExtensions = schema.vendorExtensions; 56 | 57 | if (schema.items != null) 58 | { 59 | // TODO: Handle jagged primitive array and error on jagged object array 60 | partialSchema.items = new PartialSchema(); 61 | partialSchema.items.PopulateFrom(schema.items); 62 | } 63 | 64 | partialSchema.@default = schema.@default; 65 | partialSchema.maximum = schema.maximum; 66 | partialSchema.exclusiveMaximum = schema.exclusiveMaximum; 67 | partialSchema.minimum = schema.minimum; 68 | partialSchema.exclusiveMinimum = schema.exclusiveMinimum; 69 | partialSchema.maxLength = schema.maxLength; 70 | partialSchema.minLength = schema.minLength; 71 | partialSchema.pattern = schema.pattern; 72 | partialSchema.maxItems = schema.maxItems; 73 | partialSchema.minItems = schema.minItems; 74 | partialSchema.uniqueItems = schema.uniqueItems; 75 | partialSchema.@enum = schema.@enum; 76 | partialSchema.multipleOf = schema.multipleOf; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Swashbuckle.Swagger 2 | { 3 | internal static class StringExtensions 4 | { 5 | internal static string ToCamelCase(this string value) 6 | { 7 | if (string.IsNullOrEmpty(value)) return value; 8 | return value.Substring(0, 1).ToLowerInvariant() + value.Substring(1); 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/SwaggerGeneratorOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Http.Description; 5 | 6 | namespace Swashbuckle.Swagger 7 | { 8 | public class SwaggerGeneratorOptions 9 | { 10 | public SwaggerGeneratorOptions( 11 | Func versionSupportResolver = null, 12 | IEnumerable schemes = null, 13 | IDictionary securityDefinitions = null, 14 | bool ignoreObsoleteActions = false, 15 | Func groupingKeySelector = null, 16 | IComparer groupingKeyComparer = null, 17 | IDictionary> customSchemaMappings = null, 18 | IEnumerable schemaFilters = null, 19 | IEnumerable modelFilters = null, 20 | bool ignoreObsoleteProperties = false, 21 | Func schemaIdSelector = null, 22 | bool describeAllEnumsAsStrings = false, 23 | bool describeStringEnumsInCamelCase = false, 24 | bool applyFiltersToAllSchemas = false, 25 | IEnumerable operationFilters = null, 26 | IEnumerable documentFilters = null, 27 | Func, ApiDescription> conflictingActionsResolver = null 28 | ) 29 | { 30 | VersionSupportResolver = versionSupportResolver; 31 | Schemes = schemes; 32 | SecurityDefinitions = securityDefinitions; 33 | IgnoreObsoleteActions = ignoreObsoleteActions; 34 | GroupingKeySelector = groupingKeySelector ?? DefaultGroupingKeySelector; 35 | GroupingKeyComparer = groupingKeyComparer ?? Comparer.Default; 36 | CustomSchemaMappings = customSchemaMappings ?? new Dictionary>(); 37 | SchemaFilters = schemaFilters ?? new List(); 38 | ModelFilters = modelFilters ?? new List(); 39 | IgnoreObsoleteProperties = ignoreObsoleteProperties; 40 | SchemaIdSelector = schemaIdSelector ?? DefaultSchemaIdSelector; 41 | DescribeAllEnumsAsStrings = describeAllEnumsAsStrings; 42 | DescribeStringEnumsInCamelCase = describeStringEnumsInCamelCase; 43 | ApplyFiltersToAllSchemas = applyFiltersToAllSchemas; 44 | OperationFilters = operationFilters ?? new List(); 45 | DocumentFilters = documentFilters ?? new List(); 46 | ConflictingActionsResolver = conflictingActionsResolver ?? DefaultConflictingActionsResolver; 47 | } 48 | 49 | public Func VersionSupportResolver { get; private set; } 50 | 51 | public IEnumerable Schemes { get; private set; } 52 | 53 | public IDictionary SecurityDefinitions { get; private set; } 54 | 55 | public bool IgnoreObsoleteActions { get; private set; } 56 | 57 | public Func GroupingKeySelector { get; private set; } 58 | 59 | public IComparer GroupingKeyComparer { get; private set; } 60 | 61 | public IDictionary> CustomSchemaMappings { get; private set; } 62 | 63 | public IEnumerable SchemaFilters { get; private set; } 64 | 65 | public IEnumerable ModelFilters { get; private set; } 66 | 67 | public bool IgnoreObsoleteProperties { get; private set; } 68 | 69 | public Func SchemaIdSelector { get; private set; } 70 | 71 | public bool DescribeAllEnumsAsStrings { get; private set; } 72 | 73 | public bool DescribeStringEnumsInCamelCase { get; private set; } 74 | 75 | public bool ApplyFiltersToAllSchemas { get; private set; } 76 | 77 | public IEnumerable OperationFilters { get; private set; } 78 | 79 | public IEnumerable DocumentFilters { get; private set; } 80 | 81 | public Func, ApiDescription> ConflictingActionsResolver { get; private set; } 82 | 83 | private string DefaultGroupingKeySelector(ApiDescription apiDescription) 84 | { 85 | return apiDescription.ActionDescriptor.ControllerDescriptor.ControllerName; 86 | } 87 | 88 | private static string DefaultSchemaIdSelector(Type type) 89 | { 90 | return type.FriendlyId(); 91 | } 92 | 93 | private ApiDescription DefaultConflictingActionsResolver(IEnumerable apiDescriptions) 94 | { 95 | var first = apiDescriptions.First(); 96 | throw new NotSupportedException(String.Format( 97 | "Not supported by Swagger 2.0: Multiple operations with path '{0}' and method '{1}'. " + 98 | "See the config setting - \"ResolveConflictingActions\" for a potential workaround", 99 | first.RelativePathSansQueryString(), first.HttpMethod)); 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | using System.Runtime.Serialization; 5 | using System.Text; 6 | 7 | namespace Swashbuckle.Swagger 8 | { 9 | public static class TypeExtensions 10 | { 11 | public static string FriendlyId(this Type type, bool fullyQualified = false) 12 | { 13 | var typeName = fullyQualified 14 | ? type.FullNameSansTypeParameters().Replace("+", ".") 15 | : type.Name; 16 | 17 | if (type.IsGenericType) 18 | { 19 | var genericArgumentIds = type.GetGenericArguments() 20 | .Select(t => t.FriendlyId(fullyQualified)) 21 | .ToArray(); 22 | 23 | return new StringBuilder(typeName) 24 | .Replace(string.Format("`{0}", genericArgumentIds.Count()), string.Empty) 25 | .Append(string.Format("[{0}]", string.Join(",", genericArgumentIds).TrimEnd(','))) 26 | .ToString(); 27 | } 28 | 29 | return typeName; 30 | } 31 | 32 | public static string FullNameSansTypeParameters(this Type type) 33 | { 34 | var fullName = type.FullName; 35 | if (string.IsNullOrEmpty(fullName)) 36 | fullName = type.Name; 37 | var chopIndex = fullName.IndexOf("[["); 38 | return (chopIndex == -1) ? fullName : fullName.Substring(0, chopIndex); 39 | } 40 | 41 | public static string[] GetEnumNamesForSerialization(this Type enumType) 42 | { 43 | return enumType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static) 44 | .Select(fieldInfo => 45 | { 46 | var memberAttribute = fieldInfo.GetCustomAttributes(false).OfType().FirstOrDefault(); 47 | return (memberAttribute == null || string.IsNullOrWhiteSpace(memberAttribute.Value)) 48 | ? fieldInfo.Name 49 | : memberAttribute.Value; 50 | }) 51 | .ToArray(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/XmlComments/ApplyXmlActionComments.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Reflection; 3 | using System.Text; 4 | using System.Web.Http; 5 | using System.Web.Http.Controllers; 6 | using System.Web.Http.Description; 7 | using System.Xml.XPath; 8 | using Swashbuckle.Application; 9 | using Swashbuckle.Swagger.Annotations; 10 | 11 | namespace Swashbuckle.Swagger.XmlComments 12 | { 13 | public class ApplyXmlActionComments : IOperationFilter 14 | { 15 | private const string MemberXPath = "/doc/members/member[@name='{0}']"; 16 | private const string SummaryXPath = "summary"; 17 | private const string RemarksXPath = "remarks"; 18 | private const string ParamXPath = "param[@name='{0}']"; 19 | private const string ResponseXPath = "response"; 20 | 21 | private readonly XPathDocument _xmlDoc; 22 | 23 | public ApplyXmlActionComments(string filePath) 24 | : this(new XPathDocument(filePath)) { } 25 | 26 | public ApplyXmlActionComments(XPathDocument xmlDoc) 27 | { 28 | _xmlDoc = xmlDoc; 29 | } 30 | 31 | public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) 32 | { 33 | var reflectedActionDescriptor = apiDescription.ActionDescriptor as ReflectedHttpActionDescriptor; 34 | if (reflectedActionDescriptor == null) return; 35 | 36 | XPathNavigator navigator; 37 | lock (_xmlDoc) 38 | { 39 | navigator = _xmlDoc.CreateNavigator(); 40 | } 41 | 42 | var commentId = XmlCommentsIdHelper.GetCommentIdForMethod(reflectedActionDescriptor.MethodInfo); 43 | var methodNode = navigator.SelectSingleNode(string.Format(MemberXPath, commentId)); 44 | if (methodNode == null) return; 45 | 46 | var summaryNode = methodNode.SelectSingleNode(SummaryXPath); 47 | if (summaryNode != null) 48 | operation.summary = summaryNode.ExtractContent(); 49 | 50 | var remarksNode = methodNode.SelectSingleNode(RemarksXPath); 51 | if (remarksNode != null) 52 | operation.description = remarksNode.ExtractContent(); 53 | 54 | ApplyParamComments(operation, methodNode, reflectedActionDescriptor.MethodInfo); 55 | 56 | ApplyResponseComments(operation, methodNode); 57 | 58 | ApplyDeveloperInfo(operation,apiDescription); 59 | } 60 | 61 | private static void ApplyParamComments(Operation operation, XPathNavigator methodNode, MethodInfo method) 62 | { 63 | if (operation.parameters == null) return; 64 | 65 | foreach (var parameter in operation.parameters) 66 | { 67 | // Inspect method to find the corresponding action parameter 68 | // NOTE: If a parameter binding is present (e.g. [FromUri(Name..)]), then the lookup needs 69 | // to be against the "bound" name and not the actual parameter name 70 | var actionParameter = method.GetParameters() 71 | .FirstOrDefault(paramInfo => 72 | HasBoundName(paramInfo, parameter.name) || paramInfo.Name == parameter.name 73 | ); 74 | if (actionParameter == null) continue; 75 | 76 | var paramNode = methodNode.SelectSingleNode(string.Format(ParamXPath, actionParameter.Name)); 77 | if (paramNode != null) 78 | parameter.description = paramNode.ExtractContent(); 79 | } 80 | } 81 | 82 | private static void ApplyResponseComments(Operation operation, XPathNavigator methodNode) 83 | { 84 | var responseNodes = methodNode.Select(ResponseXPath); 85 | 86 | if (responseNodes.Count > 0) 87 | { 88 | var successResponse = operation.responses.First().Value; 89 | operation.responses.Clear(); 90 | 91 | while (responseNodes.MoveNext()) 92 | { 93 | var statusCode = responseNodes.Current.GetAttribute("code", ""); 94 | var description = responseNodes.Current.ExtractContent(); 95 | 96 | var response = new Response 97 | { 98 | description = description, 99 | schema = statusCode.StartsWith("2") ? successResponse.schema : null 100 | }; 101 | operation.responses[statusCode] = response; 102 | } 103 | } 104 | } 105 | 106 | private static bool HasBoundName(ParameterInfo paramInfo, string name) 107 | { 108 | var fromUriAttribute = paramInfo.GetCustomAttributes(false) 109 | .OfType() 110 | .FirstOrDefault(); 111 | 112 | return (fromUriAttribute != null && fromUriAttribute.Name == name); 113 | } 114 | 115 | /// 116 | /// 加入开发者信息 117 | /// 118 | /// 119 | /// 120 | private static void ApplyDeveloperInfo(Operation operation, ApiDescription apiDescription) 121 | { 122 | if (!SwaggerDocsConfig.ShowDeveloper) 123 | { 124 | return; 125 | } 126 | var authorInfo = apiDescription.GetControllerAndActionAttributes().FirstOrDefault(); 127 | if (authorInfo == null) 128 | { 129 | operation.showDevStatus = false; 130 | return; 131 | } 132 | 133 | operation.developer = authorInfo.Name; 134 | operation.showDevStatus = authorInfo.Status != DevStatus.None; 135 | operation.devStatus = authorInfo.Status.ToString(); 136 | operation.devStatusName = authorInfo.GetStatusName(); 137 | operation.modifyDate = authorInfo.Time; 138 | } 139 | } 140 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/XmlComments/ApplyXmlTypeComments.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Xml.XPath; 3 | 4 | namespace Swashbuckle.Swagger.XmlComments 5 | { 6 | public class ApplyXmlTypeComments : IModelFilter 7 | { 8 | private const string MemberXPath = "/doc/members/member[@name='{0}']"; 9 | private const string SummaryTag = "summary"; 10 | 11 | private readonly XPathDocument _xmlDoc; 12 | 13 | private readonly XPathNavigator _navigator; 14 | 15 | public ApplyXmlTypeComments(string filePath) 16 | : this(new XPathDocument(filePath)) { } 17 | 18 | public ApplyXmlTypeComments(XPathDocument xmlDoc) 19 | { 20 | _xmlDoc = xmlDoc; 21 | _navigator = xmlDoc.CreateNavigator(); 22 | } 23 | 24 | public XPathNavigator XmlNavigator 25 | { 26 | get { return _navigator; } 27 | } 28 | 29 | public void Apply(Schema model, ModelFilterContext context) 30 | { 31 | var commentId = XmlCommentsIdHelper.GetCommentIdForType(context.SystemType); 32 | var typeNode = _navigator.SelectSingleNode(string.Format(MemberXPath, commentId)); 33 | 34 | if (typeNode != null) 35 | { 36 | var summaryNode = typeNode.SelectSingleNode(SummaryTag); 37 | if (summaryNode != null) 38 | model.description = summaryNode.ExtractContent(); 39 | } 40 | 41 | if (model.properties != null) 42 | { 43 | foreach (var entry in model.properties) 44 | { 45 | var jsonProperty = context.JsonObjectContract.Properties[entry.Key]; 46 | if (jsonProperty == null) continue; 47 | 48 | ApplyPropertyComments(_navigator, entry.Value, jsonProperty.PropertyInfo()); 49 | } 50 | } 51 | } 52 | 53 | private static void ApplyPropertyComments(XPathNavigator navigator, Schema propertySchema, PropertyInfo propertyInfo) 54 | { 55 | if (propertyInfo == null) return; 56 | 57 | var commentId = XmlCommentsIdHelper.GetCommentIdForProperty(propertyInfo); 58 | var propertyNode = navigator.SelectSingleNode(string.Format(MemberXPath, commentId)); 59 | if (propertyNode == null) return; 60 | 61 | var propSummaryNode = propertyNode.SelectSingleNode(SummaryTag); 62 | if (propSummaryNode != null) 63 | { 64 | propertySchema.description = propSummaryNode.ExtractContent(); 65 | } 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/XmlComments/XPathNavigatorExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Xml; 7 | using System.Xml.XPath; 8 | 9 | namespace Swashbuckle.Swagger.XmlComments 10 | { 11 | public static class XPathNavigatorExtensions 12 | { 13 | private static Regex ParamPattern = new Regex(@"<(see|paramref) (name|cref)=""([TPF]{1}:)?(?.+?)"" />"); 14 | private static Regex ConstPattern = new Regex(@"(?.+?)"); 15 | 16 | public static string ExtractContent(this XPathNavigator node) 17 | { 18 | if (node == null) return null; 19 | 20 | return XmlTextHelper.NormalizeIndentation( 21 | ConstPattern.Replace( 22 | ParamPattern.Replace(node.InnerXml, GetParamRefName), 23 | GetConstRefName) 24 | ); 25 | } 26 | 27 | private static string GetConstRefName(Match match) 28 | { 29 | if (match.Groups.Count != 2) return null; 30 | 31 | return match.Groups["display"].Value; 32 | } 33 | 34 | private static string GetParamRefName(Match match) 35 | { 36 | if (match.Groups.Count != 5) return null; 37 | 38 | return "{" + match.Groups["display"].Value + "}"; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/XmlComments/XmlCommentsIdHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Text; 4 | 5 | namespace Swashbuckle.Swagger.XmlComments 6 | { 7 | public class XmlCommentsIdHelper 8 | { 9 | public static string GetCommentIdForMethod(MethodInfo methodInfo) 10 | { 11 | var builder = new StringBuilder("M:"); 12 | AppendFullTypeName(methodInfo.DeclaringType, builder); 13 | builder.Append("."); 14 | AppendMethodName(methodInfo, builder); 15 | 16 | return builder.ToString(); 17 | } 18 | 19 | public static string GetCommentIdForType(Type type) 20 | { 21 | var builder = new StringBuilder("T:"); 22 | AppendFullTypeName(type, builder, expandGenericArgs: false); 23 | 24 | return builder.ToString(); 25 | } 26 | 27 | public static string GetCommentIdForProperty(PropertyInfo propertyInfo) 28 | { 29 | var builder = new StringBuilder("P:"); 30 | AppendFullTypeName(propertyInfo.DeclaringType, builder); 31 | builder.Append("."); 32 | AppendPropertyName(propertyInfo, builder); 33 | 34 | return builder.ToString(); 35 | } 36 | 37 | private static void AppendFullTypeName(Type type, StringBuilder builder, bool expandGenericArgs = false) 38 | { 39 | if (type.Namespace != null) 40 | { 41 | builder.Append(type.Namespace); 42 | builder.Append("."); 43 | } 44 | AppendTypeName(type, builder, expandGenericArgs); 45 | } 46 | 47 | private static void AppendTypeName(Type type, StringBuilder builder, bool expandGenericArgs) 48 | { 49 | if (type.IsNested) 50 | { 51 | AppendTypeName(type.DeclaringType, builder, false); 52 | builder.Append("."); 53 | } 54 | 55 | builder.Append(type.Name); 56 | 57 | if (expandGenericArgs) 58 | ExpandGenericArgsIfAny(type, builder); 59 | } 60 | 61 | public static void ExpandGenericArgsIfAny(Type type, StringBuilder builder) 62 | { 63 | if (type.IsGenericType) 64 | { 65 | var genericArgsBuilder = new StringBuilder("{"); 66 | 67 | var genericArgs = type.GetGenericArguments(); 68 | foreach (var argType in genericArgs) 69 | { 70 | AppendFullTypeName(argType, genericArgsBuilder, true); 71 | genericArgsBuilder.Append(","); 72 | } 73 | genericArgsBuilder.Replace(",", "}", genericArgsBuilder.Length - 1, 1); 74 | 75 | builder.Replace(string.Format("`{0}", genericArgs.Length), genericArgsBuilder.ToString()); 76 | } 77 | else if (type.IsArray) 78 | ExpandGenericArgsIfAny(type.GetElementType(), builder); 79 | } 80 | 81 | private static void AppendMethodName(MethodInfo methodInfo, StringBuilder builder) 82 | { 83 | builder.Append(methodInfo.Name); 84 | 85 | var parameters = methodInfo.GetParameters(); 86 | if (parameters.Length == 0) return; 87 | 88 | builder.Append("("); 89 | foreach (var param in parameters) 90 | { 91 | AppendFullTypeName(param.ParameterType, builder, true); 92 | builder.Append(","); 93 | } 94 | builder.Replace(",", ")", builder.Length - 1, 1); 95 | } 96 | 97 | private static void AppendPropertyName(PropertyInfo propertyInfo, StringBuilder builder) 98 | { 99 | builder.Append(propertyInfo.Name); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swagger/XmlComments/XmlTextHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Swashbuckle.Swagger.XmlComments 7 | { 8 | public static class XmlTextHelper 9 | { 10 | /// 11 | /// Messages text from an XML node produced by Visual Studio into a plainer plain text (leading whitespace normalized) 12 | /// 13 | /// The content of an XML node - could contain other XML elements within the string 14 | /// 15 | public static string NormalizeIndentation(string xmlText) 16 | { 17 | if (null == xmlText) 18 | throw new ArgumentNullException("xmlText"); 19 | 20 | string[] lines = xmlText.Split('\n'); 21 | string padding = GetCommonLeadingWhitespace(lines); 22 | 23 | int padLen = padding == null ? 0 : padding.Length; 24 | 25 | // remove leading padding from each line 26 | for (int i = 0, l = lines.Length; i < l; ++i) 27 | { 28 | string line = lines[i].TrimEnd('\r'); // remove trailing '\r' 29 | 30 | if (padLen != 0 && line.Length >= padLen && line.Substring(0, padLen) == padding) 31 | line = line.Substring(padLen); 32 | 33 | lines[i] = line; 34 | } 35 | 36 | // remove leading empty lines, but not all leading padding 37 | // remove all trailing whitespace, regardless 38 | return string.Join("\r\n", lines.SkipWhile(x => string.IsNullOrWhiteSpace(x))).TrimEnd(); 39 | } 40 | 41 | /// 42 | /// Finds the common padding prefix used on all non-empty lines. 43 | /// 44 | /// 45 | /// The common padding found on all non-blank lines - returns null when no common prefix is found 46 | static string GetCommonLeadingWhitespace(string[] lines) 47 | { 48 | if (null == lines) 49 | throw new ArgumentException("lines"); 50 | 51 | if (lines.Length == 0) 52 | return null; 53 | 54 | string[] nonEmptyLines = lines 55 | .Where(x => !string.IsNullOrWhiteSpace(x)) 56 | .ToArray(); 57 | 58 | if (nonEmptyLines.Length < 1) 59 | return null; 60 | 61 | int padLen = 0; 62 | 63 | // use the first line as a seed, and see what is shared over all nonEmptyLines 64 | string seed = nonEmptyLines[0]; 65 | for (int i = 0, l = seed.Length; i < l; ++i) 66 | { 67 | if (!char.IsWhiteSpace(seed, i)) 68 | break; 69 | 70 | if (nonEmptyLines.Any(line => line[i] != seed[i])) 71 | break; 72 | 73 | ++padLen; 74 | } 75 | 76 | if (padLen > 0) 77 | return seed.Substring(0, padLen); 78 | 79 | return null; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Swashbuckle.Core/SwaggerUi/CustomAssets/discoveryUrlSelector.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var DiscoveryUrlSelector = Backbone.View.extend({ 3 | render: function() { 4 | // Don't re-render on subsequent reloads 5 | var defaultVal = this.$el.val() 6 | if (this.$el.prop('tagName') != 'SELECT') { 7 | var select = $(''); 8 | select 9 | .css('margin', '0') 10 | .css('border', '1px solid gray') 11 | .css('padding', '3px') 12 | .css('width', '400px') 13 | .css('font-size', '0.9em'); 14 | 15 | var rootUrl = this.options.rootUrl; 16 | _.each(this.options.discoveryPaths, function(path) { 17 | var option = $(''); 18 | select.append(option); 19 | }); 20 | 21 | select.val(defaultVal); 22 | this.$el.replaceWith(select); 23 | } 24 | return this; 25 | } 26 | }); 27 | 28 | new DiscoveryUrlSelector({ 29 | el: $('#input_baseUrl'), 30 | rootUrl: swashbuckleConfig.rootUrl, 31 | discoveryPaths: swashbuckleConfig.discoveryPaths 32 | }).render(); 33 | })(); -------------------------------------------------------------------------------- /Swashbuckle.Core/SwaggerUi/CustomAssets/typography.css: -------------------------------------------------------------------------------- 1 | /* Google Font's Droid Sans */ 2 | @font-face { 3 | font-family: 'Droid Sans'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans-ttf'), format('truetype'); 7 | } 8 | /* Google Font's Droid Sans Bold */ 9 | @font-face { 10 | font-family: 'Droid Sans'; 11 | font-style: normal; 12 | font-weight: 700; 13 | src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold-ttf'), format('truetype'); 14 | } 15 | -------------------------------------------------------------------------------- /Swashbuckle.Core/SwaggerUi/EmbeddedAssetDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Swashbuckle.SwaggerUi 4 | { 5 | public class EmbeddedAssetDescriptor 6 | { 7 | public EmbeddedAssetDescriptor(Assembly containingAssembly, string name, bool isTemplate) 8 | { 9 | Assembly = containingAssembly; 10 | Name = name; 11 | IsTemplate = isTemplate; 12 | } 13 | 14 | public Assembly Assembly { get; private set; } 15 | 16 | public string Name { get; private set; } 17 | 18 | public bool IsTemplate { get; private set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/SwaggerUi/EmbeddedAssetProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace Swashbuckle.SwaggerUi 7 | { 8 | public class EmbeddedAssetProvider : IAssetProvider 9 | { 10 | private readonly IDictionary _pathToAssetMap; 11 | private readonly IDictionary _templateParams; 12 | 13 | public EmbeddedAssetProvider( 14 | IDictionary pathToAssetMap, 15 | IDictionary templateParams) 16 | { 17 | _pathToAssetMap = pathToAssetMap; 18 | _templateParams = templateParams; 19 | } 20 | 21 | public Asset GetAsset(string rootUrl, string path) 22 | { 23 | if (!_pathToAssetMap.ContainsKey(path)) 24 | throw new AssetNotFound(String.Format("Mapping not found - {0}", path)); 25 | 26 | var resourceDescriptor = _pathToAssetMap[path]; 27 | return new Asset( 28 | GetEmbeddedResourceStreamFor(resourceDescriptor, rootUrl), 29 | InferMediaTypeFrom(resourceDescriptor.Name) 30 | ); 31 | } 32 | 33 | private Stream GetEmbeddedResourceStreamFor(EmbeddedAssetDescriptor resourceDescriptor, string rootUrl) 34 | { 35 | var stream = resourceDescriptor.Assembly.GetManifestResourceStream(resourceDescriptor.Name); 36 | if (stream == null) 37 | throw new AssetNotFound(String.Format("Embedded resource not found - {0}", resourceDescriptor.Name)); 38 | 39 | if (resourceDescriptor.IsTemplate) 40 | { 41 | var templateParams = _templateParams 42 | .Union(new[] { new KeyValuePair("%(RootUrl)", rootUrl) }) 43 | .ToDictionary(entry => entry.Key, entry => entry.Value); 44 | 45 | return stream.FindAndReplace(templateParams); 46 | } 47 | 48 | return stream; 49 | } 50 | 51 | private static string InferMediaTypeFrom(string path) 52 | { 53 | var extension = path.Split('.').Last(); 54 | 55 | switch (extension) 56 | { 57 | case "css": 58 | return "text/css"; 59 | case "js": 60 | return "text/javascript"; 61 | case "gif": 62 | return "image/gif"; 63 | case "png": 64 | return "image/png"; 65 | case "eot": 66 | return "application/vnd.ms-fontobject"; 67 | case "woff": 68 | return "application/font-woff"; 69 | case "woff2": 70 | return "application/font-woff2"; 71 | case "otf": 72 | return "application/font-sfnt"; // formerly "font/opentype" 73 | case "ttf": 74 | return "application/font-sfnt"; // formerly "font/truetype" 75 | case "svg": 76 | return "image/svg+xml"; 77 | default: 78 | return "text/html"; 79 | } 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /Swashbuckle.Core/SwaggerUi/IAssetProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Swashbuckle.SwaggerUi 5 | { 6 | public interface IAssetProvider 7 | { 8 | Asset GetAsset(string rootUrl, string assetPath); 9 | } 10 | 11 | public class Asset 12 | { 13 | public Asset(Stream stream, string mediaType) 14 | { 15 | Stream = stream; 16 | MediaType = mediaType; 17 | } 18 | 19 | public Stream Stream { get; private set; } 20 | 21 | public string MediaType { get; private set; } 22 | } 23 | 24 | public class AssetNotFound : Exception 25 | { 26 | public AssetNotFound(string message) 27 | : base(message) 28 | {} 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Swashbuckle.Core/SwaggerUi/StreamExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace Swashbuckle.SwaggerUi 6 | { 7 | public static class StreamExtensions 8 | { 9 | public static Stream FindAndReplace(this Stream stream, IDictionary replacements) 10 | { 11 | var originalText = new StreamReader(stream).ReadToEnd(); 12 | var outputBuilder = new StringBuilder(originalText); 13 | 14 | foreach (var replacement in replacements) 15 | { 16 | outputBuilder.Replace(replacement.Key, replacement.Value); 17 | } 18 | 19 | return new MemoryStream(Encoding.UTF8.GetBytes(outputBuilder.ToString())); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Swashbuckle.Core/Swashbuckle.Core.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SwashbuckleEx.Core 5 | $version$ 6 | SwashbuckleEx - Swagger for WebApi 7 | 简玄冰 8 | jianxuanbing 9 | http://www.apache.org/licenses/LICENSE-2.0.html 10 | https://github.com/jianxuanbing/SwashbuckleEx 11 | false 12 | SwaggerUI WebApi Document,Base in SashbuckleEx,Added Search Api Name And Added Sinicization,Using CacheInfo 13 | Copyright 2017 14 | Swashbuckle WebApi Swagger document 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Swashbuckle.Core/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Swashbuckle.WebHost/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Swashbuckle.WebHost")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Swashbuckle.WebHost")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | //将 ComVisible 设置为 false 将使此程序集中的类型 18 | //对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("31ad7304-29a6-4305-8a86-97516c1cf1c8")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.3.0")] 36 | [assembly: AssemblyFileVersion("1.1.3.0")] 37 | [assembly: AssemblyInformationalVersion("1.1.3.0")] 38 | -------------------------------------------------------------------------------- /Swashbuckle.WebHost/Swashbuckle.WebHost.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {31AD7304-29A6-4305-8A86-97516C1CF1C8} 8 | Library 9 | Properties 10 | Swashbuckle.WebHost 11 | Swashbuckle.WebHost 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 47 | -------------------------------------------------------------------------------- /Swashbuckle.WebHost/Swashbuckle.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SwashbuckleEx 5 | $version$ 6 | SwashbuckleEx - Swagger for WebApi 7 | 简玄冰 8 | jianxuanbing 9 | http://opensource.org/licenses/BSD-3-Clause 10 | https://github.com/jianxuanbing/SwashbuckleEx 11 | false 12 | SwaggerUI WebApi Document,Base in SashbuckleEx,Added Search Api Name And Added Sinicization,Using CacheInfo 13 | Copyright 2017 14 | Swashbuckle Swagger SwaggerUi WebApi AspNet AspNetWebApi Docs 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/App_Start/SimpleCorsHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using System.Web; 8 | 9 | namespace SwashbuckleEx.WebApiTest 10 | { 11 | /// 12 | /// 简单Cors跨域处理器 13 | /// 14 | public class SimpleCorsHandler : DelegatingHandler 15 | { 16 | private const string Origin = "Origin"; 17 | private const string AccessControlRequestMethod = "Access-Control-Request-Method"; 18 | private const string AccessControlRequestHeaders = "Access-Control-Request-Headers"; 19 | private const string AccessControlAllowOrign = "Access-Control-Allow-Origin"; 20 | private const string AccessControlAllowMethods = "Access-Control-Allow-Methods"; 21 | private const string AccessControlAllowHeaders = "Access-Control-Allow-Headers"; 22 | private const string AccessControlAllowCredentials = "Access-Control-Allow-Credentials"; 23 | 24 | private const string AccessControlMaxAge = "Access-Control-Max-Age"; 25 | // 26 | // 27 | protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 28 | { 29 | bool isCrosRequest = request.Headers.Contains(Origin); 30 | bool isPrefilightRequest = request.Method == HttpMethod.Options; 31 | if (isCrosRequest) 32 | { 33 | Task taskResult = null; 34 | if (isPrefilightRequest) 35 | { 36 | taskResult = Task.Factory.StartNew(() => 37 | { 38 | HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); 39 | response.Headers.Add(AccessControlAllowOrign, 40 | request.Headers.GetValues(Origin).FirstOrDefault()); 41 | string method = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault(); 42 | //if (method != null) 43 | //{ 44 | // response.Headers.Add(AccessControlAllowMethods, method); 45 | //} 46 | string headers = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders)); 47 | if (!string.IsNullOrWhiteSpace(headers)) 48 | { 49 | response.Headers.Add(AccessControlAllowHeaders, headers); 50 | } 51 | response.Headers.Add(AccessControlAllowCredentials, "true"); 52 | response.Headers.Add(AccessControlMaxAge, "1728000"); 53 | return response; 54 | }, cancellationToken); 55 | } 56 | else 57 | { 58 | taskResult = base.SendAsync(request, cancellationToken).ContinueWith(t => 59 | { 60 | var response = t.Result; 61 | response.Headers.Add(AccessControlAllowOrign, 62 | request.Headers.GetValues(Origin).FirstOrDefault()); 63 | response.Headers.Add(AccessControlAllowCredentials, "true"); 64 | return response; 65 | }); 66 | } 67 | return taskResult; 68 | } 69 | return base.SendAsync(request, cancellationToken); 70 | } 71 | 72 | //private const string Origin = "Origin"; 73 | //private const string AccessControlRequestMethod = "Access-Control-Request-Method"; 74 | //private const string AccessControlRequestHeaders = "Access-Control-Request-Headers"; 75 | //private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin"; 76 | //private const string AccessControlAllowMethods = "Access-Control-Allow-Methods"; 77 | //private const string AccessControlAllowHeaders = "Access-Control-Allow-Headers"; 78 | 79 | //// 重写基类的发送消息方法 80 | //protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 81 | //{ 82 | // bool isCrosRequest = request.Headers.Contains(Origin); 83 | // bool isPrefilightRequest = request.Method == HttpMethod.Options; 84 | // if (isCrosRequest) 85 | // { 86 | // if (isPrefilightRequest) 87 | // { 88 | // return Task.Factory.StartNew(() => 89 | // { 90 | // var response = new HttpResponseMessage(HttpStatusCode.OK); 91 | // response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First()); 92 | 93 | // var currentAccessControlRequestMethod = 94 | // request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault(); 95 | 96 | // if (currentAccessControlRequestMethod != null) 97 | // { 98 | // response.Headers.Add(AccessControlAllowMethods, currentAccessControlRequestMethod); 99 | // } 100 | 101 | // var requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders)); 102 | // if (!requestedHeaders.IsNullOrEmpty()) 103 | // { 104 | // response.Headers.Add(AccessControlAllowHeaders, requestedHeaders); 105 | // } 106 | // return response; 107 | // }, cancellationToken); 108 | // } 109 | // return base.SendAsync(request, cancellationToken).ContinueWith(t => 110 | // { 111 | // var response = t.Result; 112 | // response.Headers.Add(AccessControlAllowOrigin, 113 | // request.Headers.GetValues(Origin).FirstOrDefault()); 114 | // return response; 115 | // }); 116 | // } 117 | // return base.SendAsync(request, cancellationToken); 118 | //} 119 | } 120 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/App_Start/SwaggerConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.Http.Description; 7 | using Swashbuckle.Application; 8 | using SwashbuckleEx.WebApiTest; 9 | using SwashbuckleEx.WebApiTest.Extensions; 10 | using SwashbuckleEx.WebApiTest.Selectors; 11 | 12 | [assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")] 13 | namespace SwashbuckleEx.WebApiTest 14 | { 15 | public class SwaggerConfig 16 | { 17 | public static void Register() 18 | { 19 | var thisAssembly = typeof(SwaggerConfig).Assembly; 20 | 21 | GlobalConfiguration.Configuration 22 | .EnableSwagger(c => 23 | { 24 | // 配置简单API文档信息-用于单个文档 25 | //c.SingleApiVersion("v1", "Test.WebApi").Contact(x => 26 | //{ 27 | // x.Email("jianxuanhuo1@126.com"); 28 | // x.Name("jian玄冰"); 29 | // x.Url("https://www.cnblogs.com/jianxuanbing"); 30 | //}).TermsOfService("jian玄冰1").License(x => 31 | //{ 32 | // x.Name("MIT"); 33 | // x.Url("https://www.cnblogs.com/jianxuanbing"); 34 | //}).Description("自定义文案内容,可以随便输入内容"); 35 | c.MultipleApiVersions(ResolveAreasSupportByRouteConstraint, (vc) => 36 | { 37 | vc.Version("Admin", "中文后台 API").Description("这个用于测试一下备注信息").TermsOfService("www.baidu.com").License( 38 | x => 39 | { 40 | x.Name("jian玄冰"); 41 | x.Url("www.baidu.2333"); 42 | }) 43 | .Contact(x => 44 | { 45 | x.Name("2017").Email("jianxuanhuo1@126.com").Url("www.baidu.xxxx"); 46 | }); 47 | vc.Version("v1", "Common API", true); 48 | 49 | vc.Version("Client", "Client API"); 50 | }); 51 | 52 | c.ApiKey("Authorization").Description("OAuth2 Auth").In("header").Name("Authorization"); 53 | //c.OAuth2("jwt").AuthorizationUrl("http://localhost:9460/oauth/token") 54 | // .TokenUrl("http://localhost:9460/oauth/token").Scopes( 55 | // x => 56 | // { 57 | // x.Add("scope", "admin"); 58 | // }); 59 | c.DocumentFilter(); 60 | 61 | c.OperationFilter(); 62 | 63 | c.IncludeXmlComments(string.Format("{0}/bin/SwashbuckleEx.WebApiTest.XML", AppDomain.CurrentDomain.BaseDirectory)); 64 | c.ShowDeveloperInfo(); 65 | }) 66 | .EnableSwaggerUi(c => 67 | { 68 | c.EnableApiKeySupport("Authorization","header"); 69 | }); 70 | } 71 | 72 | private static bool ResolveAreasSupportByRouteConstraint(ApiDescription apiDescription, string targetApiVersion) 73 | { 74 | if (targetApiVersion == "v1") 75 | { 76 | return apiDescription.Route.RouteTemplate.StartsWith("api/{controller}"); 77 | } 78 | var routeTemplateStart = "api/" + targetApiVersion; 79 | return apiDescription.Route.RouteTemplate.StartsWith(routeTemplateStart); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Http; 2 | using System.Web.Http.Dispatcher; 3 | using SwashbuckleEx.WebApiTest.Selectors; 4 | 5 | namespace SwashbuckleEx.WebApiTest 6 | { 7 | public static class WebApiConfig 8 | { 9 | public static void Register(HttpConfiguration config) 10 | { 11 | // Web API 配置和服务 12 | config.Services.Replace(typeof(IHttpControllerSelector),new NamespaceHttpControllerSelector(config)); 13 | // Web API 路由 14 | config.MapHttpAttributeRoutes(); 15 | 16 | config.Routes.MapHttpRoute( 17 | name: "AdminApi", 18 | routeTemplate: "api/Admin/{controller}/{action}/{id}", 19 | defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional, namespaces = new string[] { "SwashbuckleEx.WebApiTest.Areas.Admin.Controllers" } }); 20 | config.Routes.MapHttpRoute( 21 | name: "ClientApi", 22 | routeTemplate: "api/Client/{controller}/{action}/{id}", 23 | defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional, namespaces = new string[] { "SwashbuckleEx.WebApiTest.Areas.Client.Controllers" } }); 24 | 25 | config.Routes.MapHttpRoute( 26 | name: "CommonApi", 27 | routeTemplate: "api/{controller}/{action}/{id}", 28 | defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional, namespaces = new string[] { "SwashbuckleEx.WebApiTest.Controllers" } } 29 | ); 30 | 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Areas/Admin/Controllers/TestAController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Http; 4 | using System.Web.Http; 5 | using Swashbuckle.Swagger.Annotations; 6 | using SwashbuckleEx.WebApiTest.Extensions; 7 | using SwashbuckleEx.WebApiTest.Models; 8 | 9 | namespace SwashbuckleEx.WebApiTest.Areas.Admin.Controllers 10 | { 11 | /// 12 | /// 后台测试 相关API 13 | /// 14 | public class TestAController : ApiController 15 | { 16 | /// 17 | /// 获取后台Guid 18 | /// 19 | /// 20 | /// 测试一些内容,不想将无用的东西放在接口名称当中
21 | /// 换行输出一下内容 22 | ///
23 | [HttpGet] 24 | public Guid GetGuid() => Guid.NewGuid(); 25 | 26 | /// 27 | /// 上传文件 28 | /// 29 | [HttpPost] 30 | [Upload] 31 | public void UploadFile() 32 | { 33 | } 34 | 35 | /// 36 | /// 查看API开发状态 37 | /// 38 | [HttpGet] 39 | [ApiAuthor(Name = "jian玄冰", Status = DevStatus.Wait, Time = "2018-04-28")] 40 | public void ApiStatus() 41 | { 42 | } 43 | 44 | /// 45 | /// 获取用户信息 46 | /// 47 | [HttpGet] 48 | [SwaggerResponse(HttpStatusCode.OK, "自定义内容", Type = typeof(UserInfo))] 49 | public HttpResponseMessage GetUserInfo() => Request.CreateResponse(HttpStatusCode.OK, new UserInfo(), "application/json"); 50 | } 51 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Areas/Client/Controllers/TestAController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Http; 3 | 4 | namespace SwashbuckleEx.WebApiTest.Areas.Client.Controllers 5 | { 6 | /// 7 | /// 客户端测试 相关API 8 | /// 9 | public class TestAController : ApiController 10 | { 11 | /// 12 | /// 获取客户端Guid 13 | /// 14 | [HttpGet] 15 | [AllowAnonymous] 16 | public Guid GetGuid() => Guid.NewGuid(); 17 | } 18 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Areas/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Http; 2 | using System.Web.Mvc; 3 | using System.Web.Routing; 4 | 5 | namespace SwashbuckleEx.WebApiTest.Areas 6 | { 7 | /// 8 | /// 扩展 9 | /// 10 | public static partial class Extensions 11 | { 12 | public static Route MapHttpRoute(this AreaRegistrationContext context, string name, string routeTemplate) 13 | { 14 | return context.MapHttpRoute(name, routeTemplate, null, null); 15 | } 16 | 17 | public static Route MapHttpRoute(this AreaRegistrationContext context, string name, string routeTemplate, object defaults) 18 | { 19 | return context.MapHttpRoute(name, routeTemplate, defaults, null); 20 | } 21 | 22 | public static Route MapHttpRoute(this AreaRegistrationContext context, string name, string routeTemplate, object defaults, object constraints) 23 | { 24 | var route = context.Routes.MapHttpRoute(name, routeTemplate, defaults, constraints); 25 | if (route.DataTokens == null) 26 | { 27 | route.DataTokens = new RouteValueDictionary(); 28 | } 29 | route.DataTokens.Add("area", context.AreaName); 30 | return route; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Controllers/TestAController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Http; 3 | 4 | namespace SwashbuckleEx.WebApiTest.Controllers 5 | { 6 | /// 7 | /// 测试控制器 8 | /// 9 | public class TestAController : ApiController 10 | { 11 | /// 12 | /// 获取通用ID 13 | /// 14 | [HttpGet] 15 | public Guid GetId() => Guid.NewGuid(); 16 | 17 | /// 18 | /// 获取结果 19 | /// 20 | /// 标识 21 | [HttpGet] 22 | public string GetResult(string id) => id; 23 | } 24 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Extensions/AddUploadOperationFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Web.Http.Description; 4 | using Swashbuckle.Swagger; 5 | 6 | namespace SwashbuckleEx.WebApiTest.Extensions 7 | { 8 | /// 9 | /// 添加 上传操作过滤 10 | /// 11 | public class AddUploadOperationFilter : IOperationFilter 12 | { 13 | /// 14 | /// 重写Apply方法,加入Upload操作过滤 15 | /// 16 | public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) 17 | { 18 | var upload = apiDescription.ActionDescriptor.GetCustomAttributes().FirstOrDefault(); 19 | if (upload == null) 20 | { 21 | return; 22 | } 23 | operation.consumes.Add("application/form-data"); 24 | if (operation.parameters==null) 25 | { 26 | operation.parameters = new List(); 27 | } 28 | operation.parameters.Add(new Parameter() 29 | { 30 | name = upload.Name, 31 | @in = "formData", 32 | required = upload.Require, 33 | type = "file", 34 | description = upload.Description 35 | }); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Extensions/UploadAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SwashbuckleEx.WebApiTest.Extensions 4 | { 5 | /// 6 | /// 上传属性,用于标识接口是否包含上传信息参数 7 | /// 8 | public class UploadAttribute : Attribute 9 | { 10 | /// 11 | /// 参数名 12 | /// 13 | public string Name { get; set; } = "file"; 14 | 15 | /// 16 | /// 是否必须包含文件 17 | /// 18 | public bool Require { get; set; } = true; 19 | 20 | /// 21 | /// 备注 22 | /// 23 | public string Description { get; set; } = ""; 24 | } 25 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="SwashbuckleEx.WebApiTest.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.Http.Description; 7 | using System.Web.Http.Dispatcher; 8 | using System.Web.Mvc; 9 | using System.Web.Routing; 10 | using Swashbuckle.Application; 11 | using SwashbuckleEx.WebApiTest.Selectors; 12 | 13 | namespace SwashbuckleEx.WebApiTest 14 | { 15 | public class WebApiApplication : System.Web.HttpApplication 16 | { 17 | protected void Application_Start() 18 | { 19 | //AreaRegistration.RegisterAllAreas(); 20 | GlobalConfiguration.Configure(WebApiConfig.Register); 21 | // WebApi支持Area 22 | //GlobalConfiguration.Configuration.Services.Replace(typeof(IApiExplorer), 23 | // new AreaApiExplorer(GlobalConfiguration.Configuration.Services.GetApiExplorer(), 24 | // GlobalConfiguration.Configuration)); 25 | //GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), 26 | // new AreaHttpControllerSelector(GlobalConfiguration.Configuration)); 27 | GlobalConfiguration.Configuration.MessageHandlers.Add(new SimpleCorsHandler()); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Models/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | 6 | namespace SwashbuckleEx.WebApiTest.Models 7 | { 8 | /// 9 | /// 用户信息 10 | /// 11 | public class UserInfo 12 | { 13 | /// 14 | /// 名称 15 | /// 16 | public string Name { get; set; } 17 | 18 | /// 19 | /// 手机号码 20 | /// 21 | public string Phone { get; set; } 22 | 23 | /// 24 | /// 头像 25 | /// 26 | public string Avactor { get; set; } 27 | 28 | /// 29 | /// 账号 30 | /// 31 | public string Account { get; set; } 32 | } 33 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过下列特性集 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("SwashbuckleEx.WebApiTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SwashbuckleEx.WebApiTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | // 对 COM 组件不可见。如果需要 19 | // 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID 23 | [assembly: Guid("42bff3de-68b0-4dd0-96e1-2bf29975f522")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 内部版本号 30 | // 修订版本 31 | // 32 | // 可以指定所有值,也可以使用“修订号”和“内部版本号”的默认值, 33 | // 方法是按如下所示使用 "*": 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Selectors/AreaHttpControllerSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net.Http; 6 | using System.Reflection; 7 | using System.Web; 8 | using System.Web.Http; 9 | using System.Web.Http.Controllers; 10 | using System.Web.Http.Dispatcher; 11 | using System.Web.Http.Routing; 12 | 13 | namespace SwashbuckleEx.WebApiTest.Selectors 14 | { 15 | /// 16 | /// WebApi区域控制器选择器 17 | /// 18 | public class AreaHttpControllerSelector : DefaultHttpControllerSelector 19 | { 20 | /// 21 | /// 区域路由变量名 22 | /// 23 | private const string AreaRouteVariableName = "area"; 24 | 25 | /// 26 | /// Http配置 27 | /// 28 | private readonly HttpConfiguration _configuration; 29 | 30 | /// 31 | /// Api控制器类型字典 32 | /// 33 | private readonly Lazy> _apiControllerTypes; 34 | 35 | /// 36 | /// 初始化一个类型的实例 37 | /// 38 | /// Http配置 39 | public AreaHttpControllerSelector(HttpConfiguration configuration) : base(configuration) 40 | { 41 | _configuration = configuration; 42 | _apiControllerTypes = new Lazy>(GetControllerTypes); 43 | } 44 | 45 | /// 46 | /// 获取控制器类型字典 47 | /// 48 | /// 49 | private static ConcurrentDictionary GetControllerTypes() 50 | { 51 | Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 52 | Dictionary types = assemblies 53 | .SelectMany(a => a 54 | .GetTypes().Where(t => 55 | !t.IsAbstract && 56 | t.Name.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase) && 57 | typeof(IHttpController).IsAssignableFrom(t))) 58 | .ToDictionary(t => t.FullName, t => t); 59 | return new ConcurrentDictionary(types); 60 | } 61 | 62 | /// 63 | /// 由Http请求获取控制台描述信息 64 | /// 65 | /// Http请求消息 66 | /// 67 | public override HttpControllerDescriptor SelectController(HttpRequestMessage request) 68 | { 69 | return GetApiController(request); 70 | } 71 | 72 | /// 73 | /// 获取Api控制器 74 | /// 75 | /// Http请求消息 76 | /// 77 | private HttpControllerDescriptor GetApiController(HttpRequestMessage request) 78 | { 79 | string areaName = GetAreaName(request); 80 | string controllerName = GetControllerName(request); 81 | if (controllerName == null) 82 | { 83 | throw new InvalidOperationException("获取的Api控制器名称为空"); 84 | } 85 | Type type = GetControllerType(areaName, controllerName); 86 | return new HttpControllerDescriptor(_configuration, controllerName, type); 87 | } 88 | 89 | /// 90 | /// 获取区域名 91 | /// 92 | /// Http请求消息 93 | /// 94 | private static string GetAreaName(HttpRequestMessage request) 95 | { 96 | IHttpRouteData data = request.GetRouteData(); 97 | object areaName; 98 | if (data.Route == null || data.Route.DataTokens == null) 99 | { 100 | if (data.Values.TryGetValue(AreaRouteVariableName, out areaName)) 101 | { 102 | return areaName.ToString(); 103 | } 104 | return null; 105 | } 106 | return data.Route.DataTokens.TryGetValue(AreaRouteVariableName, out areaName) ? areaName.ToString() : null; 107 | } 108 | 109 | /// 110 | /// 获取控制器类型 111 | /// 112 | /// 区域名 113 | /// 控制器名 114 | /// 115 | private Type GetControllerType(string areaName, string controllerName) 116 | { 117 | IEnumerable> query = _apiControllerTypes.Value.AsEnumerable(); 118 | query = string.IsNullOrWhiteSpace(areaName) ? query.WithoutAreaName() : query.ByAreaName(areaName); 119 | Type type = query.ByControllerName(controllerName).Select(m => m.Value).SingleOrDefault(); 120 | if (type == null) 121 | { 122 | throw new Exception(string.Format("未找到名称为“{0}”的Api控制器",controllerName)); 123 | } 124 | return type; 125 | } 126 | } 127 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Selectors/ControllerTypeSpecifications.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Web; 6 | using System.Web.Http.Dispatcher; 7 | 8 | namespace SwashbuckleEx.WebApiTest.Selectors 9 | { 10 | /// 11 | /// 控制器类型规范 扩展 12 | /// 13 | internal static class ControllerTypeSpecifications 14 | { 15 | /// 16 | /// 根据区域名获取键值对 17 | /// 18 | /// 键值对列表 19 | /// 区域名 20 | /// 21 | public static IEnumerable> ByAreaName( 22 | this IEnumerable> query, string areaName) 23 | { 24 | string areaNameToFind = string.Format(CultureInfo.CurrentCulture, ".{0}.", areaName); 25 | return query.Where(x => x.Key.IndexOf(areaNameToFind, StringComparison.OrdinalIgnoreCase) != -1); 26 | } 27 | 28 | /// 29 | /// 获取不包含区域名的键值对 30 | /// 31 | /// 键值对列表 32 | /// 33 | public static IEnumerable> WithoutAreaName( 34 | this IEnumerable> query) 35 | { 36 | return query.Where(x => x.Key.IndexOf(".areas.", StringComparison.OrdinalIgnoreCase) == -1); 37 | } 38 | 39 | /// 40 | /// 根据控制器名获取键值对 41 | /// 42 | /// 键值对列表 43 | /// 控制器名 44 | /// 45 | public static IEnumerable> ByControllerName( 46 | this IEnumerable> query, string controllerName) 47 | { 48 | string controllerNameToFind = string.Format(CultureInfo.InvariantCulture, ".{0}{1}", controllerName, 49 | DefaultHttpControllerSelector.ControllerSuffix); 50 | return query.Where(x => x.Key.EndsWith(controllerNameToFind, StringComparison.OrdinalIgnoreCase)); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Selectors/NamespaceHttpControllerSelector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Net.Http; 7 | using System.Web; 8 | using System.Web.Http; 9 | using System.Web.Http.Controllers; 10 | using System.Web.Http.Dispatcher; 11 | 12 | namespace SwashbuckleEx.WebApiTest.Selectors 13 | { 14 | /// 15 | /// 扩展自DefaultHttpControllerSelector类的控制器选择器,目前在用 16 | /// 17 | public class NamespaceHttpControllerSelector : DefaultHttpControllerSelector 18 | { 19 | private const string NamespaceRouteVariableName = "namespaces"; 20 | private readonly HttpConfiguration _configuration; 21 | private readonly Lazy> _apiControllerCache; 22 | /// 23 | /// 构造函数 24 | /// 25 | /// 26 | public NamespaceHttpControllerSelector(HttpConfiguration configuration) 27 | : base(configuration) 28 | { 29 | _configuration = configuration; 30 | _apiControllerCache = new Lazy>(new Func>(InitializeApiControllerCache)); 31 | } 32 | /// 33 | /// 初始化ApiController实例 34 | /// 35 | /// 36 | private ConcurrentDictionary InitializeApiControllerCache() 37 | { 38 | IAssembliesResolver assembliesResolver = this._configuration.Services.GetAssembliesResolver(); 39 | var types = this._configuration.Services.GetHttpControllerTypeResolver().GetControllerTypes(assembliesResolver).ToDictionary(t => t.FullName, t => t); 40 | return new ConcurrentDictionary(types); 41 | } 42 | /// 43 | /// 获取Controller全名 44 | /// 45 | /// 46 | /// 47 | public IEnumerable GetControllerFullName(HttpRequestMessage request, string controllerName) 48 | { 49 | object namespaceName; 50 | var data = request.GetRouteData(); 51 | IEnumerable keys = _apiControllerCache.Value.ToDictionary, string, Type>(t => t.Key, t => t.Value, StringComparer.CurrentCultureIgnoreCase).Keys.ToList(); 52 | if (!data.Values.TryGetValue(NamespaceRouteVariableName, out namespaceName)) 53 | { 54 | return from k in keys 55 | where k.EndsWith(string.Format(".{0}{1}", controllerName, 56 | DefaultHttpControllerSelector.ControllerSuffix), StringComparison.CurrentCultureIgnoreCase) 57 | select k; 58 | } 59 | string[] namespaces = (string[])namespaceName; 60 | return from n in namespaces 61 | join k in keys on string.Format("{0}.{1}{2}", n, controllerName, 62 | DefaultHttpControllerSelector.ControllerSuffix).ToLower() equals k.ToLower() 63 | select k; 64 | } 65 | /// 66 | /// 获取Controller 67 | /// 68 | /// 69 | public override HttpControllerDescriptor SelectController(HttpRequestMessage request) 70 | { 71 | Type type; 72 | if (request == null) 73 | { 74 | throw new ArgumentNullException("request"); 75 | } 76 | string controllerName = this.GetControllerName(request); 77 | if (string.IsNullOrEmpty(controllerName)) 78 | { 79 | throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("无法通过API路由匹配到您所请求的URI '{0}'", new object[] { request.RequestUri }))); 80 | } 81 | IEnumerable fullNames = GetControllerFullName(request, controllerName); 82 | if (fullNames.Count() == 0) 83 | { 84 | throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("无法通过API路由匹配到您所请求的URI '{0}'", new object[] { request.RequestUri }))); 85 | } 86 | if (this._apiControllerCache.Value.TryGetValue(fullNames.First(), out type)) 87 | { 88 | return new HttpControllerDescriptor(_configuration, controllerName, type); 89 | } 90 | throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("无法通过API路由匹配到您所请求的URI '{0}'", new object[] { request.RequestUri }))); 91 | } 92 | /// 93 | /// 获取ControllerMapping 94 | /// 95 | /// 96 | public override IDictionary GetControllerMapping() 97 | { 98 | return _apiControllerCache.Value.ToDictionary(c => c.Key, c => new HttpControllerDescriptor(_configuration, c.Value.Name.Substring(0, c.Value.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length), c.Value), StringComparer.OrdinalIgnoreCase); 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Selectors/SwaggerAreasSupportDocumentFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Web; 6 | using System.Web.Http.Description; 7 | using System.Web.Http.Dispatcher; 8 | using Swashbuckle.Swagger; 9 | 10 | namespace SwashbuckleEx.WebApiTest.Selectors 11 | { 12 | /// 13 | /// Swagger区域文档过滤器 14 | /// 15 | public class SwaggerAreasSupportDocumentFilter:IDocumentFilter 16 | { 17 | /// 18 | /// 申请处理 19 | /// 20 | /// 21 | /// 22 | /// 23 | public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer) 24 | { 25 | IDictionary replacePaths=new ConcurrentDictionary(); 26 | foreach (var item in swaggerDoc.paths) 27 | { 28 | string key = item.Key; 29 | var value = item.Value; 30 | var keys = key.Split('/'); 31 | 32 | if (keys[3].IndexOf('.')!=-1) 33 | { 34 | // 区域路径 35 | string areasName = keys[2]; 36 | string namespaceFullName = keys[3]; 37 | var directoryNames = namespaceFullName.Split('.'); 38 | string namespaceName = directoryNames[3]; 39 | if (areasName.Equals(namespaceName, StringComparison.OrdinalIgnoreCase)) 40 | { 41 | string controllerName = directoryNames[5]; 42 | replacePaths.Add( 43 | item.Key.Replace(namespaceFullName, 44 | controllerName.Substring(0, 45 | controllerName.Length - DefaultHttpControllerSelector.ControllerSuffix.Length)), 46 | value); 47 | } 48 | } 49 | else if(keys[2].IndexOf('.')!=-1) 50 | { 51 | // 基础路径 52 | string namespaceFullName = keys[2]; 53 | var directoryNames = namespaceFullName.Split('.'); 54 | bool isControllers = directoryNames[2].Equals("Controllers", StringComparison.OrdinalIgnoreCase); 55 | string controllerName = directoryNames[3]; 56 | if (isControllers) 57 | { 58 | replacePaths.Add( 59 | item.Key.Replace(namespaceFullName, 60 | controllerName.Substring(0, 61 | controllerName.Length - DefaultHttpControllerSelector.ControllerSuffix.Length)), value); 62 | } 63 | } 64 | } 65 | swaggerDoc.paths = replacePaths; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using Microsoft.Owin; 6 | using Owin; 7 | using SwashbuckleEx.WebApiTest; 8 | 9 | [assembly:OwinStartup(typeof(Startup))] 10 | namespace SwashbuckleEx.WebApiTest 11 | { 12 | 13 | public class Startup 14 | { 15 | /// 16 | /// 配置 17 | /// 18 | /// 19 | public void Configuration(IAppBuilder app) 20 | { 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 30 | 31 | -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 31 | 32 | -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 58 | 59 | -------------------------------------------------------------------------------- /SwashbuckleEx.WebApiTest/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwashbuckleEx.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Swashbuckle.Core", "Swashbuckle.Core\Swashbuckle.Core.csproj", "{15E76579-E0C4-4CD4-9083-0E04F9FD531D}" 7 | EndProject 8 | Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "swagger-ui", "swagger-ui\", "{B667E34E-F9DA-4F87-87BC-BBAB0FCD9530}" 9 | ProjectSection(WebsiteProperties) = preProject 10 | TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0" 11 | Debug.AspNetCompiler.VirtualPath = "/localhost_9235" 12 | Debug.AspNetCompiler.PhysicalPath = "swagger-ui\" 13 | Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_9235\" 14 | Debug.AspNetCompiler.Updateable = "true" 15 | Debug.AspNetCompiler.ForceOverwrite = "true" 16 | Debug.AspNetCompiler.FixedNames = "false" 17 | Debug.AspNetCompiler.Debug = "True" 18 | Release.AspNetCompiler.VirtualPath = "/localhost_9235" 19 | Release.AspNetCompiler.PhysicalPath = "swagger-ui\" 20 | Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_9235\" 21 | Release.AspNetCompiler.Updateable = "true" 22 | Release.AspNetCompiler.ForceOverwrite = "true" 23 | Release.AspNetCompiler.FixedNames = "false" 24 | Release.AspNetCompiler.Debug = "False" 25 | VWDPort = "9235" 26 | SlnRelativePath = "swagger-ui\" 27 | EndProjectSection 28 | EndProject 29 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Swashbuckle.WebHost", "Swashbuckle.WebHost\Swashbuckle.WebHost.csproj", "{31AD7304-29A6-4305-8A86-97516C1CF1C8}" 30 | EndProject 31 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SwashbuckleEx.WebApiTest", "SwashbuckleEx.WebApiTest\SwashbuckleEx.WebApiTest.csproj", "{42BFF3DE-68B0-4DD0-96E1-2BF29975F522}" 32 | EndProject 33 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B0A2397D-7BD8-4C4B-B49D-8BF47EAD27DD}" 34 | ProjectSection(SolutionItems) = preProject 35 | Publish.bat = Publish.bat 36 | Publish.SwashbuckleEx.bat = Publish.SwashbuckleEx.bat 37 | README.md = README.md 38 | EndProjectSection 39 | EndProject 40 | Global 41 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 42 | Debug|Any CPU = Debug|Any CPU 43 | Release|Any CPU = Release|Any CPU 44 | EndGlobalSection 45 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 46 | {15E76579-E0C4-4CD4-9083-0E04F9FD531D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {15E76579-E0C4-4CD4-9083-0E04F9FD531D}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {15E76579-E0C4-4CD4-9083-0E04F9FD531D}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {15E76579-E0C4-4CD4-9083-0E04F9FD531D}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {B667E34E-F9DA-4F87-87BC-BBAB0FCD9530}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {B667E34E-F9DA-4F87-87BC-BBAB0FCD9530}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {B667E34E-F9DA-4F87-87BC-BBAB0FCD9530}.Release|Any CPU.ActiveCfg = Debug|Any CPU 53 | {B667E34E-F9DA-4F87-87BC-BBAB0FCD9530}.Release|Any CPU.Build.0 = Debug|Any CPU 54 | {31AD7304-29A6-4305-8A86-97516C1CF1C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {31AD7304-29A6-4305-8A86-97516C1CF1C8}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {31AD7304-29A6-4305-8A86-97516C1CF1C8}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {31AD7304-29A6-4305-8A86-97516C1CF1C8}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {42BFF3DE-68B0-4DD0-96E1-2BF29975F522}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {42BFF3DE-68B0-4DD0-96E1-2BF29975F522}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {42BFF3DE-68B0-4DD0-96E1-2BF29975F522}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {42BFF3DE-68B0-4DD0-96E1-2BF29975F522}.Release|Any CPU.Build.0 = Release|Any CPU 62 | EndGlobalSection 63 | GlobalSection(SolutionProperties) = preSolution 64 | HideSolutionNode = FALSE 65 | EndGlobalSection 66 | EndGlobal 67 | -------------------------------------------------------------------------------- /swagger-ui/css/ext.css: -------------------------------------------------------------------------------- 1 | .controller-summary{color:#10a54a!important;word-break:keep-all;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:250px;text-align:right;cursor:default}fieldset.search{background-color:#fff;border:1px solid #bebebe;border-radius:4px;height:20px;margin:auto;padding:4px;width:60%}fieldset.search input[type=text]{background:none repeat scroll 0 0 transparent;border:medium none;box-shadow:none!important;color:#999;float:left;height:100%;margin:0;padding:0;width:85%}fieldset.search button[type=submit]{background-color:transparent;background-image:url(../images/search.png);background-position:100% 0;background-repeat:no-repeat;border:medium none;box-shadow:none;color:#999;float:right;height:100%;margin:0;max-width:17px;padding:0;width:10%} -------------------------------------------------------------------------------- /swagger-ui/css/reset.css: -------------------------------------------------------------------------------- 1 | a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-collapse:collapse;border-spacing:0} -------------------------------------------------------------------------------- /swagger-ui/css/style.css: -------------------------------------------------------------------------------- 1 | .swagger-section #header a#logo{font-size:1.5em;font-weight:700;text-decoration:none;padding:20px 0 20px 40px}#text-head{font-size:80px;font-family:Roboto,sans-serif;color:#fff;float:right;margin-right:20%}.navbar-fixed-top .navbar-brand,.navbar-fixed-top .navbar-nav,.navbar-header{height:auto}.navbar-inverse{background-color:#000;border-color:#000}#navbar-brand{margin-left:20%}.navtext{font-size:10px}.h1,h1{font-size:60px}.navbar-default .navbar-header .navbar-brand{color:#a2dfee}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#393939;font-family:Arvo,serif;font-size:1.5em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#525252;padding-left:0;display:block;clear:none;float:left;font-family:Arvo,serif;font-weight:700}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#0a0a0a}.container1{width:1500px;margin:auto;margin-top:0;background-repeat:no-repeat;background-position:-40px -20px;margin-bottom:210px}.container-inner{width:1200px;margin:auto;background-color:hsla(192,8%,88%,.75);padding-bottom:40px;padding-top:40px;border-radius:15px}.header-content{padding:0;width:1000px}.title1{font-size:80px;font-family:Vollkorn,serif;color:#404040;text-align:center;padding-top:40px;padding-bottom:100px}#icon{margin-top:-18px}.subtext{font-size:25px;font-style:italic;color:#08b;text-align:right;padding-right:250px}.bg-primary{background-color:#00468b}.navbar-default .nav>li>a,.navbar-default .nav>li>a:focus,.navbar-default .nav>li>a:focus:hover,.navbar-default .nav>li>a:hover{color:#08b}.text-faded{font-size:25px;font-family:Vollkorn,serif}.section-heading{font-family:Vollkorn,serif;font-size:45px;padding-bottom:10px}hr{border-color:#00468b;padding-bottom:10px}.description{margin-top:20px;padding-bottom:200px}.description li{font-family:Vollkorn,serif;font-size:25px;color:#525252;margin-left:28%;padding-top:5px}.gap{margin-top:200px}.troubleshootingtext{color:hsla(0,0%,100%,.7);padding-left:30%}.troubleshootingtext li{list-style-type:circle;font-size:25px;padding-bottom:5px}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.block.response_body.json:hover{cursor:pointer}.backdrop{color:blue}#myModal{height:100%}.modal-backdrop{bottom:0;position:fixed}.curl{padding:10px;font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em;max-height:400px;margin-top:5px;overflow-y:auto;background-color:#fcf6db;border:1px solid #e5e0c6;border-radius:4px}.curl_title{font-size:1.1em;margin:0;padding:15px 0 5px;font-family:Open Sans,Helvetica Neue,Arial,sans-serif;font-weight:500;line-height:1.1}.footer{display:none}.swagger-section .swagger-ui-wrap h2{padding:0}h2{margin:0;margin-bottom:5px}.markdown p,.swagger-section .swagger-ui-wrap .code{font-size:15px;font-family:Arvo,serif}.swagger-section .swagger-ui-wrap b{font-family:Arvo,serif}#signin:hover{cursor:pointer}.dropdown-menu{padding:15px}.navbar-right .dropdown-menu{left:0;right:auto}#signinbutton{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b}.navbar-default .nav>li .details{color:#000;text-transform:none;font-size:15px;font-weight:400;font-family:Open Sans,sans-serif;font-style:italic;line-height:20px;top:-2px}.navbar-default .nav>li .details:hover{color:#000}#signout{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b} -------------------------------------------------------------------------------- /swagger-ui/css/typography.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/css/typography.css -------------------------------------------------------------------------------- /swagger-ui/fonts/DroidSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/fonts/DroidSans-Bold.ttf -------------------------------------------------------------------------------- /swagger-ui/fonts/DroidSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/fonts/DroidSans.ttf -------------------------------------------------------------------------------- /swagger-ui/images/collapse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/collapse.gif -------------------------------------------------------------------------------- /swagger-ui/images/expand.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/expand.gif -------------------------------------------------------------------------------- /swagger-ui/images/explorer_icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/explorer_icons.png -------------------------------------------------------------------------------- /swagger-ui/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/favicon-16x16.png -------------------------------------------------------------------------------- /swagger-ui/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/favicon-32x32.png -------------------------------------------------------------------------------- /swagger-ui/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/favicon.ico -------------------------------------------------------------------------------- /swagger-ui/images/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/logo_small.png -------------------------------------------------------------------------------- /swagger-ui/images/pet_store_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/pet_store_api.png -------------------------------------------------------------------------------- /swagger-ui/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/search.png -------------------------------------------------------------------------------- /swagger-ui/images/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/throbber.gif -------------------------------------------------------------------------------- /swagger-ui/images/wordnik_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/swagger-ui/images/wordnik_api.png -------------------------------------------------------------------------------- /swagger-ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Swagger UI 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 144 | 145 | 146 | 147 | 163 | 164 |
 
165 |
166 | 167 | 168 | -------------------------------------------------------------------------------- /swagger-ui/lang/ca.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Advertència: Obsolet", 6 | "Implementation Notes":"Notes d'implementació", 7 | "Response Class":"Classe de la Resposta", 8 | "Status":"Estatus", 9 | "Parameters":"Paràmetres", 10 | "Parameter":"Paràmetre", 11 | "Value":"Valor", 12 | "Description":"Descripció", 13 | "Parameter Type":"Tipus del Paràmetre", 14 | "Data Type":"Tipus de la Dada", 15 | "Response Messages":"Missatges de la Resposta", 16 | "HTTP Status Code":"Codi d'Estatus HTTP", 17 | "Reason":"Raó", 18 | "Response Model":"Model de la Resposta", 19 | "Request URL":"URL de la Sol·licitud", 20 | "Response Body":"Cos de la Resposta", 21 | "Response Code":"Codi de la Resposta", 22 | "Response Headers":"Capçaleres de la Resposta", 23 | "Hide Response":"Amagar Resposta", 24 | "Try it out!":"Prova-ho!", 25 | "Show/Hide":"Mostrar/Amagar", 26 | "List Operations":"Llista Operacions", 27 | "Expand Operations":"Expandir Operacions", 28 | "Raw":"Cru", 29 | "can't parse JSON. Raw result":"no puc analitzar el JSON. Resultat cru", 30 | "Example Value":"Valor d'Exemple", 31 | "Model Schema":"Esquema del Model", 32 | "Model":"Model", 33 | "apply":"aplicar", 34 | "Username":"Nom d'usuari", 35 | "Password":"Contrasenya", 36 | "Terms of service":"Termes del servei", 37 | "Created by":"Creat per", 38 | "See more at":"Veure més en", 39 | "Contact the developer":"Contactar amb el desenvolupador", 40 | "api version":"versió de la api", 41 | "Response Content Type":"Tipus de Contingut de la Resposta", 42 | "fetching resource":"recollint recurs", 43 | "fetching resource list":"recollins llista de recursos", 44 | "Explore":"Explorant", 45 | "Show Swagger Petstore Example Apis":"Mostrar API d'Exemple Swagger Petstore", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"No es pot llegir del servidor. Potser no teniu la configuració de control d'accés apropiada.", 47 | "Please specify the protocol for":"Si us plau, especifiqueu el protocol per a", 48 | "Can't read swagger JSON from":"No es pot llegir el JSON de swagger des de", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Finalitzada la càrrega del recurs informatiu. Renderitzant Swagger UI", 50 | "Unable to read api":"No es pot llegir l'api", 51 | "from path":"des de la ruta", 52 | "server returned":"el servidor ha retornat", 53 | "Last Update Time":"Last Update Time", 54 | "Developer":"Developer" 55 | }); 56 | -------------------------------------------------------------------------------- /swagger-ui/lang/el.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Προειδοποίηση: Έχει αποσυρθεί", 6 | "Implementation Notes":"Σημειώσεις Υλοποίησης", 7 | "Response Class":"Απόκριση", 8 | "Status":"Κατάσταση", 9 | "Parameters":"Παράμετροι", 10 | "Parameter":"Παράμετρος", 11 | "Value":"Τιμή", 12 | "Description":"Περιγραφή", 13 | "Parameter Type":"Τύπος Παραμέτρου", 14 | "Data Type":"Τύπος Δεδομένων", 15 | "Response Messages":"Μηνύματα Απόκρισης", 16 | "HTTP Status Code":"Κωδικός Κατάστασης HTTP", 17 | "Reason":"Αιτιολογία", 18 | "Response Model":"Μοντέλο Απόκρισης", 19 | "Request URL":"URL Αιτήματος", 20 | "Response Body":"Σώμα Απόκρισης", 21 | "Response Code":"Κωδικός Απόκρισης", 22 | "Response Headers":"Επικεφαλίδες Απόκρισης", 23 | "Hide Response":"Απόκρυψη Απόκρισης", 24 | "Headers":"Επικεφαλίδες", 25 | "Try it out!":"Δοκιμάστε το!", 26 | "Show/Hide":"Εμφάνιση/Απόκρυψη", 27 | "List Operations":"Λίστα Λειτουργιών", 28 | "Expand Operations":"Ανάπτυξη Λειτουργιών", 29 | "Raw":"Ακατέργαστο", 30 | "can't parse JSON. Raw result":"αδυναμία ανάλυσης JSON. Ακατέργαστο αποτέλεσμα", 31 | "Example Value":"Παράδειγμα Τιμής", 32 | "Model Schema":"Σχήμα Μοντέλου", 33 | "Model":"Μοντέλο", 34 | "Click to set as parameter value":"Πατήστε για να θέσετε τιμή παραμέτρου", 35 | "apply":"εφαρμογή", 36 | "Username":"Όνομα χρήση", 37 | "Password":"Κωδικός πρόσβασης", 38 | "Terms of service":"Όροι χρήσης", 39 | "Created by":"Δημιουργήθηκε από", 40 | "See more at":"Δείτε περισσότερα στο", 41 | "Contact the developer":"Επικοινωνήστε με τον προγραμματιστή", 42 | "api version":"έκδοση api", 43 | "Response Content Type":"Τύπος Περιεχομένου Απόκρισης", 44 | "Parameter content type:":"Τύπος περιεχομένου παραμέτρου:", 45 | "fetching resource":"παραλαβή πόρου", 46 | "fetching resource list":"παραλαβή λίστας πόρων", 47 | "Explore":"Εξερεύνηση", 48 | "Show Swagger Petstore Example Apis":"Εμφάνιση Api Δειγμάτων Petstore του Swagger", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Αδυναμία ανάγνωσης από τον εξυπηρετητή. Μπορεί να μην έχει κατάλληλες ρυθμίσεις για access-control-origin.", 50 | "Please specify the protocol for":"Παρακαλώ προσδιορίστε το πρωτόκολλο για", 51 | "Can't read swagger JSON from":"Αδυναμία ανάγνωσης swagger JSON από", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"Ολοκλήρωση Φόρτωσης Πληροφορικών Πόρου. Παρουσίαση Swagger UI", 53 | "Unable to read api":"Αδυναμία ανάγνωσης api", 54 | "from path":"από το μονοπάτι", 55 | "server returned":"ο εξυπηρετηρής επέστρεψε", 56 | "Last Update Time":"Last Update Time", 57 | "Developer":"Developer" 58 | }); 59 | -------------------------------------------------------------------------------- /swagger-ui/lang/en.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Warning: Deprecated", 6 | "Implementation Notes":"Implementation Notes", 7 | "Response Class":"Response Class", 8 | "Status":"Status", 9 | "Parameters":"Parameters", 10 | "Parameter":"Parameter", 11 | "Value":"Value", 12 | "Description":"Description", 13 | "Parameter Type":"Parameter Type", 14 | "Data Type":"Data Type", 15 | "Response Messages":"Response Messages", 16 | "HTTP Status Code":"HTTP Status Code", 17 | "Reason":"Reason", 18 | "Response Model":"Response Model", 19 | "Request URL":"Request URL", 20 | "Response Body":"Response Body", 21 | "Response Code":"Response Code", 22 | "Response Headers":"Response Headers", 23 | "Hide Response":"Hide Response", 24 | "Headers":"Headers", 25 | "Try it out!":"Try it out!", 26 | "Show/Hide":"Show/Hide", 27 | "List Operations":"List Operations", 28 | "Expand Operations":"Expand Operations", 29 | "Raw":"Raw", 30 | "can't parse JSON. Raw result":"can't parse JSON. Raw result", 31 | "Example Value":"Example Value", 32 | "Model Schema":"Model Schema", 33 | "Model":"Model", 34 | "Click to set as parameter value":"Click to set as parameter value", 35 | "apply":"apply", 36 | "Username":"Username", 37 | "Password":"Password", 38 | "Terms of service":"Terms of service", 39 | "Created by":"Created by", 40 | "See more at":"See more at", 41 | "Contact the developer":"Contact the developer", 42 | "api version":"api version", 43 | "Response Content Type":"Response Content Type", 44 | "Parameter content type:":"Parameter content type:", 45 | "fetching resource":"fetching resource", 46 | "fetching resource list":"fetching resource list", 47 | "Explore":"Explore", 48 | "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", 50 | "Please specify the protocol for":"Please specify the protocol for", 51 | "Can't read swagger JSON from":"Can't read swagger JSON from", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", 53 | "Unable to read api":"Unable to read api", 54 | "from path":"from path", 55 | "server returned":"server returned", 56 | "Last Update Time":"Last Update Time", 57 | "Developer":"Developer" 58 | }); 59 | -------------------------------------------------------------------------------- /swagger-ui/lang/es.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Advertencia: Obsoleto", 6 | "Implementation Notes":"Notas de implementación", 7 | "Response Class":"Clase de la Respuesta", 8 | "Status":"Status", 9 | "Parameters":"Parámetros", 10 | "Parameter":"Parámetro", 11 | "Value":"Valor", 12 | "Description":"Descripción", 13 | "Parameter Type":"Tipo del Parámetro", 14 | "Data Type":"Tipo del Dato", 15 | "Response Messages":"Mensajes de la Respuesta", 16 | "HTTP Status Code":"Código de Status HTTP", 17 | "Reason":"Razón", 18 | "Response Model":"Modelo de la Respuesta", 19 | "Request URL":"URL de la Solicitud", 20 | "Response Body":"Cuerpo de la Respuesta", 21 | "Response Code":"Código de la Respuesta", 22 | "Response Headers":"Encabezados de la Respuesta", 23 | "Hide Response":"Ocultar Respuesta", 24 | "Try it out!":"Pruébalo!", 25 | "Show/Hide":"Mostrar/Ocultar", 26 | "List Operations":"Listar Operaciones", 27 | "Expand Operations":"Expandir Operaciones", 28 | "Raw":"Crudo", 29 | "can't parse JSON. Raw result":"no puede parsear el JSON. Resultado crudo", 30 | "Example Value":"Valor de Ejemplo", 31 | "Model Schema":"Esquema del Modelo", 32 | "Model":"Modelo", 33 | "apply":"aplicar", 34 | "Username":"Nombre de usuario", 35 | "Password":"Contraseña", 36 | "Terms of service":"Términos de Servicio", 37 | "Created by":"Creado por", 38 | "See more at":"Ver más en", 39 | "Contact the developer":"Contactar al desarrollador", 40 | "api version":"versión de la api", 41 | "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta", 42 | "fetching resource":"buscando recurso", 43 | "fetching resource list":"buscando lista del recurso", 44 | "Explore":"Explorar", 45 | "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.", 47 | "Please specify the protocol for":"Por favor, especificar el protocola para", 48 | "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI", 50 | "Unable to read api":"No se puede leer la api", 51 | "from path":"desde ruta", 52 | "server returned":"el servidor retornó", 53 | "Last Update Time":"Last Update Time", 54 | "Developer":"Developer" 55 | }); 56 | -------------------------------------------------------------------------------- /swagger-ui/lang/fr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Avertissement : Obsolète", 6 | "Implementation Notes":"Notes d'implémentation", 7 | "Response Class":"Classe de la réponse", 8 | "Status":"Statut", 9 | "Parameters":"Paramètres", 10 | "Parameter":"Paramètre", 11 | "Value":"Valeur", 12 | "Description":"Description", 13 | "Parameter Type":"Type du paramètre", 14 | "Data Type":"Type de données", 15 | "Response Messages":"Messages de la réponse", 16 | "HTTP Status Code":"Code de statut HTTP", 17 | "Reason":"Raison", 18 | "Response Model":"Modèle de réponse", 19 | "Request URL":"URL appelée", 20 | "Response Body":"Corps de la réponse", 21 | "Response Code":"Code de la réponse", 22 | "Response Headers":"En-têtes de la réponse", 23 | "Hide Response":"Cacher la réponse", 24 | "Headers":"En-têtes", 25 | "Try it out!":"Testez !", 26 | "Show/Hide":"Afficher/Masquer", 27 | "List Operations":"Liste des opérations", 28 | "Expand Operations":"Développer les opérations", 29 | "Raw":"Brut", 30 | "can't parse JSON. Raw result":"impossible de décoder le JSON. Résultat brut", 31 | "Example Value":"Exemple la valeur", 32 | "Model Schema":"Définition du modèle", 33 | "Model":"Modèle", 34 | "apply":"appliquer", 35 | "Username":"Nom d'utilisateur", 36 | "Password":"Mot de passe", 37 | "Terms of service":"Conditions de service", 38 | "Created by":"Créé par", 39 | "See more at":"Voir plus sur", 40 | "Contact the developer":"Contacter le développeur", 41 | "api version":"version de l'api", 42 | "Response Content Type":"Content Type de la réponse", 43 | "fetching resource":"récupération de la ressource", 44 | "fetching resource list":"récupération de la liste de ressources", 45 | "Explore":"Explorer", 46 | "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger", 47 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.", 48 | "Please specify the protocol for":"Veuillez spécifier un protocole pour", 49 | "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de", 50 | "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI", 51 | "Unable to read api":"Impossible de lire l'api", 52 | "from path":"à partir du chemin", 53 | "server returned":"réponse du serveur", 54 | "Last Update Time":"Last Update Time", 55 | "Developer":"Developer" 56 | }); 57 | -------------------------------------------------------------------------------- /swagger-ui/lang/geo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"ყურადღება: აღარ გამოიყენება", 6 | "Implementation Notes":"იმპლემენტაციის აღწერა", 7 | "Response Class":"რესპონს კლასი", 8 | "Status":"სტატუსი", 9 | "Parameters":"პარამეტრები", 10 | "Parameter":"პარამეტრი", 11 | "Value":"მნიშვნელობა", 12 | "Description":"აღწერა", 13 | "Parameter Type":"პარამეტრის ტიპი", 14 | "Data Type":"მონაცემის ტიპი", 15 | "Response Messages":"პასუხი", 16 | "HTTP Status Code":"HTTP სტატუსი", 17 | "Reason":"მიზეზი", 18 | "Response Model":"რესპონს მოდელი", 19 | "Request URL":"მოთხოვნის URL", 20 | "Response Body":"პასუხის სხეული", 21 | "Response Code":"პასუხის კოდი", 22 | "Response Headers":"პასუხის ჰედერები", 23 | "Hide Response":"დამალე პასუხი", 24 | "Headers":"ჰედერები", 25 | "Try it out!":"ცადე !", 26 | "Show/Hide":"გამოჩენა/დამალვა", 27 | "List Operations":"ოპერაციების სია", 28 | "Expand Operations":"ოპერაციები ვრცლად", 29 | "Raw":"ნედლი", 30 | "can't parse JSON. Raw result":"JSON-ის დამუშავება ვერ მოხერხდა. ნედლი პასუხი", 31 | "Example Value":"მაგალითი", 32 | "Model Schema":"მოდელის სტრუქტურა", 33 | "Model":"მოდელი", 34 | "Click to set as parameter value":"პარამეტრისთვის მნიშვნელობის მისანიჭებლად, დააკლიკე", 35 | "apply":"გამოყენება", 36 | "Username":"მოხმარებელი", 37 | "Password":"პაროლი", 38 | "Terms of service":"მომსახურების პირობები", 39 | "Created by":"შექმნა", 40 | "See more at":"ნახე ვრცლად", 41 | "Contact the developer":"დაუკავშირდი დეველოპერს", 42 | "api version":"api ვერსია", 43 | "Response Content Type":"პასუხის კონტენტის ტიპი", 44 | "Parameter content type:":"პარამეტრის კონტენტის ტიპი:", 45 | "fetching resource":"რესურსების მიღება", 46 | "fetching resource list":"რესურსების სიის მიღება", 47 | "Explore":"ნახვა", 48 | "Show Swagger Petstore Example Apis":"ნახე Swagger Petstore სამაგალითო Api", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"სერვერთან დაკავშირება ვერ ხერხდება. შეამოწმეთ access-control-origin.", 50 | "Please specify the protocol for":"მიუთითეთ პროტოკოლი", 51 | "Can't read swagger JSON from":"swagger JSON წაკითხვა ვერ მოხერხდა", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"რესურსების ჩატვირთვა სრულდება. Swagger UI რენდერდება", 53 | "Unable to read api":"api წაკითხვა ვერ მოხერხდა", 54 | "from path":"მისამართიდან", 55 | "server returned":"სერვერმა დააბრუნა", 56 | "Last Update Time":"Last Update Time", 57 | "Developer":"Developer" 58 | }); 59 | -------------------------------------------------------------------------------- /swagger-ui/lang/it.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Attenzione: Deprecato", 6 | "Implementation Notes":"Note di implementazione", 7 | "Response Class":"Classe della risposta", 8 | "Status":"Stato", 9 | "Parameters":"Parametri", 10 | "Parameter":"Parametro", 11 | "Value":"Valore", 12 | "Description":"Descrizione", 13 | "Parameter Type":"Tipo di parametro", 14 | "Data Type":"Tipo di dato", 15 | "Response Messages":"Messaggi della risposta", 16 | "HTTP Status Code":"Codice stato HTTP", 17 | "Reason":"Motivo", 18 | "Response Model":"Modello di risposta", 19 | "Request URL":"URL della richiesta", 20 | "Response Body":"Corpo della risposta", 21 | "Response Code":"Oggetto della risposta", 22 | "Response Headers":"Intestazioni della risposta", 23 | "Hide Response":"Nascondi risposta", 24 | "Try it out!":"Provalo!", 25 | "Show/Hide":"Mostra/Nascondi", 26 | "List Operations":"Mostra operazioni", 27 | "Expand Operations":"Espandi operazioni", 28 | "Raw":"Grezzo (raw)", 29 | "can't parse JSON. Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).", 30 | "Model Schema":"Schema del modello", 31 | "Model":"Modello", 32 | "apply":"applica", 33 | "Username":"Nome utente", 34 | "Password":"Password", 35 | "Terms of service":"Condizioni del servizio", 36 | "Created by":"Creato da", 37 | "See more at":"Informazioni aggiuntive:", 38 | "Contact the developer":"Contatta lo sviluppatore", 39 | "api version":"versione api", 40 | "Response Content Type":"Tipo di contenuto (content type) della risposta", 41 | "fetching resource":"recuperando la risorsa", 42 | "fetching resource list":"recuperando lista risorse", 43 | "Explore":"Esplora", 44 | "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore", 45 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.", 46 | "Please specify the protocol for":"Si prega di specificare il protocollo per", 47 | "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:", 48 | "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata", 49 | "Unable to read api":"Impossibile leggere la api", 50 | "from path":"da cartella", 51 | "server returned":"il server ha restituito", 52 | "Last Update Time":"Last Update Time", 53 | "Developer":"Developer" 54 | }); 55 | -------------------------------------------------------------------------------- /swagger-ui/lang/ja.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"警告: 廃止予定", 6 | "Implementation Notes":"実装メモ", 7 | "Response Class":"レスポンスクラス", 8 | "Status":"ステータス", 9 | "Parameters":"パラメータ群", 10 | "Parameter":"パラメータ", 11 | "Value":"値", 12 | "Description":"説明", 13 | "Parameter Type":"パラメータタイプ", 14 | "Data Type":"データタイプ", 15 | "Response Messages":"レスポンスメッセージ", 16 | "HTTP Status Code":"HTTPステータスコード", 17 | "Reason":"理由", 18 | "Response Model":"レスポンスモデル", 19 | "Request URL":"リクエストURL", 20 | "Response Body":"レスポンスボディ", 21 | "Response Code":"レスポンスコード", 22 | "Response Headers":"レスポンスヘッダ", 23 | "Hide Response":"レスポンスを隠す", 24 | "Headers":"ヘッダ", 25 | "Try it out!":"実際に実行!", 26 | "Show/Hide":"表示/非表示", 27 | "List Operations":"操作一覧", 28 | "Expand Operations":"操作の展開", 29 | "Raw":"未加工", 30 | "can't parse JSON. Raw result":"JSONへ解釈できません. 未加工の結果", 31 | "Example Value":"値の例", 32 | "Model Schema":"モデルスキーマ", 33 | "Model":"モデル", 34 | "Click to set as parameter value":"パラメータ値と設定するにはクリック", 35 | "apply":"実行", 36 | "Username":"ユーザ名", 37 | "Password":"パスワード", 38 | "Terms of service":"サービス利用規約", 39 | "Created by":"Created by", 40 | "See more at":"詳細を見る", 41 | "Contact the developer":"開発者に連絡", 42 | "api version":"APIバージョン", 43 | "Response Content Type":"レスポンス コンテンツタイプ", 44 | "Parameter content type:":"パラメータコンテンツタイプ:", 45 | "fetching resource":"リソースの取得", 46 | "fetching resource list":"リソース一覧の取得", 47 | "Explore":"調査", 48 | "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"サーバから読み込めません. 適切なaccess-control-origin設定を持っていない可能性があります.", 50 | "Please specify the protocol for":"プロトコルを指定してください", 51 | "Can't read swagger JSON from":"次からswagger JSONを読み込めません", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています", 53 | "Unable to read api":"APIを読み込めません", 54 | "from path":"次のパスから", 55 | "server returned":"サーバからの返答", 56 | "Last Update Time":"Last Update Time", 57 | "Developer":"Developer" 58 | }); 59 | -------------------------------------------------------------------------------- /swagger-ui/lang/ko-kr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"경고:폐기예정됨", 6 | "Implementation Notes":"구현 노트", 7 | "Response Class":"응답 클래스", 8 | "Status":"상태", 9 | "Parameters":"매개변수들", 10 | "Parameter":"매개변수", 11 | "Value":"값", 12 | "Description":"설명", 13 | "Parameter Type":"매개변수 타입", 14 | "Data Type":"데이터 타입", 15 | "Response Messages":"응답 메세지", 16 | "HTTP Status Code":"HTTP 상태 코드", 17 | "Reason":"원인", 18 | "Response Model":"응답 모델", 19 | "Request URL":"요청 URL", 20 | "Response Body":"응답 본문", 21 | "Response Code":"응답 코드", 22 | "Response Headers":"응답 헤더", 23 | "Hide Response":"응답 숨기기", 24 | "Headers":"헤더", 25 | "Try it out!":"써보기!", 26 | "Show/Hide":"보이기/숨기기", 27 | "List Operations":"목록 작업", 28 | "Expand Operations":"전개 작업", 29 | "Raw":"원본", 30 | "can't parse JSON. Raw result":"JSON을 파싱할수 없음. 원본결과:", 31 | "Model Schema":"모델 스키마", 32 | "Model":"모델", 33 | "apply":"적용", 34 | "Username":"사용자 이름", 35 | "Password":"암호", 36 | "Terms of service":"이용약관", 37 | "Created by":"작성자", 38 | "See more at":"추가정보:", 39 | "Contact the developer":"개발자에게 문의", 40 | "api version":"api버전", 41 | "Response Content Type":"응답Content Type", 42 | "fetching resource":"리소스 가져오기", 43 | "fetching resource list":"리소스 목록 가져오기", 44 | "Explore":"탐색", 45 | "Show Swagger Petstore Example Apis":"Swagger Petstore 예제 보기", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"서버로부터 읽어들일수 없습니다. access-control-origin 설정이 올바르지 않을수 있습니다.", 47 | "Please specify the protocol for":"다음을 위한 프로토콜을 정하세요", 48 | "Can't read swagger JSON from":"swagger JSON 을 다음으로 부터 읽을수 없습니다", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"리소스 정보 불러오기 완료. Swagger UI 랜더링", 50 | "Unable to read api":"api를 읽을 수 없습니다.", 51 | "from path":"다음 경로로 부터", 52 | "server returned":"서버 응답함.", 53 | "Last Update Time":"Last Update Time", 54 | "Developer":"Developer" 55 | }); 56 | -------------------------------------------------------------------------------- /swagger-ui/lang/lang.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 方言 3 | */ 4 | var locales={ 5 | en:{ 6 | "Warning: Deprecated":"Warning: Deprecated", 7 | "Implementation Notes":"Implementation Notes", 8 | "Response Class":"Response Class", 9 | "Status":"Status", 10 | "Parameters":"Parameters", 11 | "Parameter":"Parameter", 12 | "Value":"Value", 13 | "Description":"Description", 14 | "Parameter Type":"Parameter Type", 15 | "Data Type":"Data Type", 16 | "Response Messages":"Response Messages", 17 | "HTTP Status Code":"HTTP Status Code", 18 | "Reason":"Reason", 19 | "Response Model":"Response Model", 20 | "Request URL":"Request URL", 21 | "Response Body":"Response Body", 22 | "Response Code":"Response Code", 23 | "Response Headers":"Response Headers", 24 | "Hide Response":"Hide Response", 25 | "Headers":"Headers", 26 | "Try it out!":"Try it out!", 27 | "Show/Hide":"Show/Hide", 28 | "List Operations":"List Operations", 29 | "Expand Operations":"Expand Operations", 30 | "Raw":"Raw", 31 | "can't parse JSON. Raw result":"can't parse JSON. Raw result", 32 | "Example Value":"Example Value", 33 | "Model Schema":"Model Schema", 34 | "Model":"Model", 35 | "Click to set as parameter value":"Click to set as parameter value", 36 | "apply":"apply", 37 | "Username":"Username", 38 | "Password":"Password", 39 | "Terms of service":"Terms of service", 40 | "Created by":"Created by", 41 | "See more at":"See more at", 42 | "Contact the developer":"Contact the developer", 43 | "api version":"api version", 44 | "Response Content Type":"Response Content Type", 45 | "Parameter content type:":"Parameter content type:", 46 | "fetching resource":"fetching resource", 47 | "fetching resource list":"fetching resource list", 48 | "Explore":"Explore", 49 | "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", 50 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", 51 | "Please specify the protocol for":"Please specify the protocol for", 52 | "Can't read swagger JSON from":"Can't read swagger JSON from", 53 | "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", 54 | "Unable to read api":"Unable to read api", 55 | "from path":"from path", 56 | "server returned":"server returned", 57 | "Last Update Time":"Last Update Time", 58 | "Developer":"Developer" 59 | }, 60 | zh_CN:{ 61 | "Warning: Deprecated":"警告:已过时", 62 | "Implementation Notes":"实现备注", 63 | "Response Class":"响应类", 64 | "Status":"状态", 65 | "Parameters":"参数", 66 | "Parameter":"参数", 67 | "Value":"值", 68 | "Description":"描述", 69 | "Parameter Type":"参数类型", 70 | "Data Type":"数据类型", 71 | "Response Messages":"响应消息", 72 | "HTTP Status Code":"HTTP状态码", 73 | "Reason":"原因", 74 | "Response Model":"响应模型", 75 | "Request URL":"请求URL", 76 | "Response Body":"响应体", 77 | "Response Code":"响应码", 78 | "Response Headers":"响应头", 79 | "Hide Response":"隐藏响应", 80 | "Headers":"头", 81 | "Try it out!":"试一下!", 82 | "Show/Hide":"显示/隐藏", 83 | "List Operations":"显示操作", 84 | "Expand Operations":"展开操作", 85 | "Raw":"原始", 86 | "can't parse JSON. Raw result":"无法解析JSON. 原始结果", 87 | "Example Value":"示例", 88 | "Click to set as parameter value":"点击设置参数", 89 | "Model Schema":"模型架构", 90 | "Model":"模型", 91 | "apply":"应用", 92 | "Username":"用户名", 93 | "Password":"密码", 94 | "Terms of service":"服务条款", 95 | "Created by":"创建者", 96 | "See more at":"查看更多:", 97 | "Contact the developer":"联系开发者", 98 | "api version":"api版本", 99 | "Response Content Type":"响应Content Type", 100 | "Parameter content type:":"参数类型:", 101 | "fetching resource":"正在获取资源", 102 | "fetching resource list":"正在获取资源列表", 103 | "Explore":"浏览", 104 | "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis", 105 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。", 106 | "Please specify the protocol for":"请指定协议:", 107 | "Can't read swagger JSON from":"无法读取swagger JSON于", 108 | "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI", 109 | "Unable to read api":"无法读取api", 110 | "from path":"从路径", 111 | "server returned":"服务器返回", 112 | "CORS Tip": "


提示:可能是因为Ajax跨域请求导致。查看解决方式。", 113 | "Last Update Time":"最后更新时间", 114 | "Developer":"开发者" 115 | } 116 | } -------------------------------------------------------------------------------- /swagger-ui/lang/pl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Uwaga: Wycofane", 6 | "Implementation Notes":"Uwagi Implementacji", 7 | "Response Class":"Klasa Odpowiedzi", 8 | "Status":"Status", 9 | "Parameters":"Parametry", 10 | "Parameter":"Parametr", 11 | "Value":"Wartość", 12 | "Description":"Opis", 13 | "Parameter Type":"Typ Parametru", 14 | "Data Type":"Typ Danych", 15 | "Response Messages":"Wiadomości Odpowiedzi", 16 | "HTTP Status Code":"Kod Statusu HTTP", 17 | "Reason":"Przyczyna", 18 | "Response Model":"Model Odpowiedzi", 19 | "Request URL":"URL Wywołania", 20 | "Response Body":"Treść Odpowiedzi", 21 | "Response Code":"Kod Odpowiedzi", 22 | "Response Headers":"Nagłówki Odpowiedzi", 23 | "Hide Response":"Ukryj Odpowiedź", 24 | "Headers":"Nagłówki", 25 | "Try it out!":"Wypróbuj!", 26 | "Show/Hide":"Pokaż/Ukryj", 27 | "List Operations":"Lista Operacji", 28 | "Expand Operations":"Rozwiń Operacje", 29 | "Raw":"Nieprzetworzone", 30 | "can't parse JSON. Raw result":"nie można przetworzyć pliku JSON. Nieprzetworzone dane", 31 | "Model Schema":"Schemat Modelu", 32 | "Model":"Model", 33 | "apply":"użyj", 34 | "Username":"Nazwa użytkownika", 35 | "Password":"Hasło", 36 | "Terms of service":"Warunki używania", 37 | "Created by":"Utworzone przez", 38 | "See more at":"Zobacz więcej na", 39 | "Contact the developer":"Kontakt z deweloperem", 40 | "api version":"wersja api", 41 | "Response Content Type":"Typ Zasobu Odpowiedzi", 42 | "fetching resource":"ładowanie zasobu", 43 | "fetching resource list":"ładowanie listy zasobów", 44 | "Explore":"Eksploruj", 45 | "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.", 47 | "Please specify the protocol for":"Proszę podać protokół dla", 48 | "Can't read swagger JSON from":"Nie można odczytać swagger JSON z", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI", 50 | "Unable to read api":"Nie można odczytać api", 51 | "from path":"ze ścieżki", 52 | "server returned":"serwer zwrócił", 53 | "Last Update Time":"Last Update Time", 54 | "Developer":"Developer" 55 | }); 56 | -------------------------------------------------------------------------------- /swagger-ui/lang/pt.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Aviso: Depreciado", 6 | "Implementation Notes":"Notas de Implementação", 7 | "Response Class":"Classe de resposta", 8 | "Status":"Status", 9 | "Parameters":"Parâmetros", 10 | "Parameter":"Parâmetro", 11 | "Value":"Valor", 12 | "Description":"Descrição", 13 | "Parameter Type":"Tipo de parâmetro", 14 | "Data Type":"Tipo de dados", 15 | "Response Messages":"Mensagens de resposta", 16 | "HTTP Status Code":"Código de status HTTP", 17 | "Reason":"Razão", 18 | "Response Model":"Modelo resposta", 19 | "Request URL":"URL requisição", 20 | "Response Body":"Corpo da resposta", 21 | "Response Code":"Código da resposta", 22 | "Response Headers":"Cabeçalho da resposta", 23 | "Headers":"Cabeçalhos", 24 | "Hide Response":"Esconder resposta", 25 | "Try it out!":"Tente agora!", 26 | "Show/Hide":"Mostrar/Esconder", 27 | "List Operations":"Listar operações", 28 | "Expand Operations":"Expandir operações", 29 | "Raw":"Cru", 30 | "can't parse JSON. Raw result":"Falha ao analisar JSON. Resulto cru", 31 | "Model Schema":"Modelo esquema", 32 | "Model":"Modelo", 33 | "apply":"Aplicar", 34 | "Username":"Usuário", 35 | "Password":"Senha", 36 | "Terms of service":"Termos do serviço", 37 | "Created by":"Criado por", 38 | "See more at":"Veja mais em", 39 | "Contact the developer":"Contate o desenvolvedor", 40 | "api version":"Versão api", 41 | "Response Content Type":"Tipo de conteúdo da resposta", 42 | "fetching resource":"busca recurso", 43 | "fetching resource list":"buscando lista de recursos", 44 | "Explore":"Explorar", 45 | "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin", 47 | "Please specify the protocol for":"Por favor especifique o protocolo", 48 | "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI", 50 | "Unable to read api":"Não foi possível ler api", 51 | "from path":"do caminho", 52 | "server returned":"servidor retornou", 53 | "Last Update Time":"Last Update Time", 54 | "Developer":"Developer" 55 | }); 56 | -------------------------------------------------------------------------------- /swagger-ui/lang/ru.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Предупреждение: Устарело", 6 | "Implementation Notes":"Заметки", 7 | "Response Class":"Пример ответа", 8 | "Status":"Статус", 9 | "Parameters":"Параметры", 10 | "Parameter":"Параметр", 11 | "Value":"Значение", 12 | "Description":"Описание", 13 | "Parameter Type":"Тип параметра", 14 | "Data Type":"Тип данных", 15 | "HTTP Status Code":"HTTP код", 16 | "Reason":"Причина", 17 | "Response Model":"Структура ответа", 18 | "Request URL":"URL запроса", 19 | "Response Body":"Тело ответа", 20 | "Response Code":"HTTP код ответа", 21 | "Response Headers":"Заголовки ответа", 22 | "Hide Response":"Спрятать ответ", 23 | "Headers":"Заголовки", 24 | "Response Messages":"Что может прийти в ответ", 25 | "Try it out!":"Попробовать!", 26 | "Show/Hide":"Показать/Скрыть", 27 | "List Operations":"Операции кратко", 28 | "Expand Operations":"Операции подробно", 29 | "Raw":"В сыром виде", 30 | "can't parse JSON. Raw result":"Не удается распарсить ответ:", 31 | "Example Value":"Пример", 32 | "Model Schema":"Структура", 33 | "Model":"Описание", 34 | "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра", 35 | "apply":"применить", 36 | "Username":"Имя пользователя", 37 | "Password":"Пароль", 38 | "Terms of service":"Условия использования", 39 | "Created by":"Разработано", 40 | "See more at":"Еще тут", 41 | "Contact the developer":"Связаться с разработчиком", 42 | "api version":"Версия API", 43 | "Response Content Type":"Content Type ответа", 44 | "Parameter content type:":"Content Type параметра:", 45 | "fetching resource":"Получение ресурса", 46 | "fetching resource list":"Получение ресурсов", 47 | "Explore":"Показать", 48 | "Show Swagger Petstore Example Apis":"Показать примеры АПИ", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа", 50 | "Please specify the protocol for":"Пожалуйста, укажите протокол для", 51 | "Can't read swagger JSON from":"Не получается прочитать swagger json из", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим", 53 | "Unable to read api":"Не удалось прочитать api", 54 | "from path":"по адресу", 55 | "server returned":"сервер сказал", 56 | "Last Update Time":"Last Update Time", 57 | "Developer":"Developer" 58 | }); 59 | -------------------------------------------------------------------------------- /swagger-ui/lang/tr.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"Uyarı: Deprecated", 6 | "Implementation Notes":"Gerçekleştirim Notları", 7 | "Response Class":"Dönen Sınıf", 8 | "Status":"Statü", 9 | "Parameters":"Parametreler", 10 | "Parameter":"Parametre", 11 | "Value":"Değer", 12 | "Description":"Açıklama", 13 | "Parameter Type":"Parametre Tipi", 14 | "Data Type":"Veri Tipi", 15 | "Response Messages":"Dönüş Mesajı", 16 | "HTTP Status Code":"HTTP Statü Kodu", 17 | "Reason":"Gerekçe", 18 | "Response Model":"Dönüş Modeli", 19 | "Request URL":"İstek URL", 20 | "Response Body":"Dönüş İçeriği", 21 | "Response Code":"Dönüş Kodu", 22 | "Response Headers":"Dönüş Üst Bilgileri", 23 | "Hide Response":"Dönüşü Gizle", 24 | "Headers":"Üst Bilgiler", 25 | "Try it out!":"Dene!", 26 | "Show/Hide":"Göster/Gizle", 27 | "List Operations":"Operasyonları Listele", 28 | "Expand Operations":"Operasyonları Aç", 29 | "Raw":"Ham", 30 | "can't parse JSON. Raw result":"JSON çözümlenemiyor. Ham sonuç", 31 | "Model Schema":"Model Şema", 32 | "Model":"Model", 33 | "apply":"uygula", 34 | "Username":"Kullanıcı Adı", 35 | "Password":"Parola", 36 | "Terms of service":"Servis şartları", 37 | "Created by":"Oluşturan", 38 | "See more at":"Daha fazlası için", 39 | "Contact the developer":"Geliştirici ile İletişime Geçin", 40 | "api version":"api versiyon", 41 | "Response Content Type":"Dönüş İçerik Tipi", 42 | "fetching resource":"kaynak getiriliyor", 43 | "fetching resource list":"kaynak listesi getiriliyor", 44 | "Explore":"Keşfet", 45 | "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör", 46 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.", 47 | "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz", 48 | "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor", 49 | "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor", 50 | "Unable to read api":"api okunamadı", 51 | "from path":"yoldan", 52 | "server returned":"sunucuya dönüldü", 53 | "Last Update Time":"Last Update Time", 54 | "Developer":"Developer" 55 | }); 56 | -------------------------------------------------------------------------------- /swagger-ui/lang/translator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Translator for documentation pages. 5 | * 6 | * To enable translation you should include one of language-files in your index.html 7 | * after . 8 | * For example - 9 | * 10 | * If you wish to translate some new texts you should do two things: 11 | * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too. 12 | * 2. Mark that text it templates this way New Phrase or . 13 | * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate. 14 | * 15 | */ 16 | window.SwaggerTranslator = { 17 | 18 | _words:[], 19 | 20 | translate: function(sel) { 21 | var $this = this; 22 | sel = sel || '[data-sw-translate]'; 23 | 24 | $(sel).each(function() { 25 | $(this).html($this._tryTranslate($(this).html())); 26 | 27 | $(this).val($this._tryTranslate($(this).val())); 28 | $(this).attr('title', $this._tryTranslate($(this).attr('title'))); 29 | 30 | }); 31 | }, 32 | 33 | _tryTranslate: function(word) { 34 | return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word; 35 | }, 36 | 37 | learn: function(wordsMap) { 38 | this._words = wordsMap; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /swagger-ui/lang/zh-cn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint quotmark: double */ 4 | window.SwaggerTranslator.learn({ 5 | "Warning: Deprecated":"警告:已过时", 6 | "Implementation Notes":"接口说明", 7 | "Response Class":"响应类", 8 | "Status":"状态", 9 | "Parameters":"参数", 10 | "Parameter":"参数", 11 | "Value":"值", 12 | "Description":"描述", 13 | "Parameter Type":"参数类型", 14 | "Data Type":"数据类型", 15 | "Response Messages":"响应消息", 16 | "HTTP Status Code":"HTTP状态码", 17 | "Reason":"原因", 18 | "Response Model":"响应模型", 19 | "Request URL":"请求URL", 20 | "Response Body":"响应体", 21 | "Response Code":"响应码", 22 | "Response Headers":"响应头", 23 | "Hide Response":"隐藏响应", 24 | "Headers":"头", 25 | "Try it out!":"试一下!", 26 | "Show/Hide":"显示/隐藏", 27 | "List Operations":"显示操作", 28 | "Expand Operations":"展开操作", 29 | "Raw":"原始", 30 | "can't parse JSON. Raw result":"无法解析JSON. 原始结果", 31 | "Example Value":"示例", 32 | "Click to set as parameter value":"点击设置参数", 33 | "Model Schema":"模型架构", 34 | "Model":"模型", 35 | "apply":"应用", 36 | "Username":"用户名", 37 | "Password":"密码", 38 | "Terms of service":"服务条款", 39 | "Created by":"创建者", 40 | "See more at":"查看更多:", 41 | "Contact the developer":"联系开发者", 42 | "api version":"api版本", 43 | "Response Content Type":"响应Content Type", 44 | "Parameter content type:":"参数类型:", 45 | "fetching resource":"正在获取资源", 46 | "fetching resource list":"正在获取资源列表", 47 | "Explore":"浏览", 48 | "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis", 49 | "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。", 50 | "Please specify the protocol for":"请指定协议:", 51 | "Can't read swagger JSON from":"无法读取swagger JSON于", 52 | "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI", 53 | "Unable to read api":"无法读取api", 54 | "from path":"从路径", 55 | "server returned":"服务器返回", 56 | "Last Update Time":"最后更新时间", 57 | "Developer":"开发者" 58 | }); 59 | -------------------------------------------------------------------------------- /swagger-ui/lib/highlight.9.1.0.pack_extended.js: -------------------------------------------------------------------------------- 1 | "use strict";!function(){var h,l;h=hljs.configure,hljs.configure=function(l){var i=l.highlightSizeThreshold;hljs.highlightSizeThreshold=i===+i?i:null,h.call(this,l)},l=hljs.highlightBlock,hljs.highlightBlock=function(h){var i=h.innerHTML,g=hljs.highlightSizeThreshold;(null==g||g>i.length)&&l.call(hljs,h)}}(); -------------------------------------------------------------------------------- /swagger-ui/lib/jquery.ba-bbq.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){function n(e){return"string"==typeof e}function r(e){var t=g.call(arguments,1);return function(){return e.apply(this,t.concat(g.call(arguments)))}}function o(e){return e.replace(/^[^#]*#?(.*)$/,"$1")}function a(e){return e.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function i(r,o,a,i,c){var u,s,p,h,d;return i!==f?(p=a.match(r?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/),d=p[3]||"",2===c&&n(i)?s=i.replace(r?R:E,""):(h=l(p[2]),i=n(i)?l[r?A:w](i):i,s=2===c?i:1===c?e.extend({},i,h):e.extend({},h,i),s=b(s),r&&(s=s.replace(m,y))),u=p[1]+(r?"#":s||!p[1]?"?":"")+s+d):u=o(a!==f?a:t[S][q]),u}function c(e,t,r){return t===f||"boolean"==typeof t?(r=t,t=b[e?A:w]()):t=n(t)?t.replace(e?R:E,""):t,l(t,r)}function u(t,r,o,a){return n(o)||"object"==typeof o||(a=o,o=r,r=f),this.each(function(){var n=e(this),i=r||v()[(this.nodeName||"").toLowerCase()]||"",c=i&&n.attr(i)||"";n.attr(i,b[t](c,o,a))})}var f,s,l,p,h,d,v,m,g=Array.prototype.slice,y=decodeURIComponent,b=e.param,$=e.bbq=e.bbq||{},x=e.event.special,j="hashchange",w="querystring",A="fragment",N="elemUrlAttr",S="location",q="href",C="src",E=/^.*\?|#.*$/g,R=/^.*\#/,U={};b[w]=r(i,0,a),b[A]=s=r(i,1,o),s.noEscape=function(t){t=t||"";var n=e.map(t.split(""),encodeURIComponent);m=new RegExp(n.join("|"),"g")},s.noEscape(",/"),e.deparam=l=function(t,n){var r={},o={"true":!0,"false":!1,"null":null};return e.each(t.replace(/\+/g," ").split("&"),function(t,a){var i,c=a.split("="),u=y(c[0]),s=r,l=0,p=u.split("]["),h=p.length-1;if(/\[/.test(p[0])&&/\]$/.test(p[h])?(p[h]=p[h].replace(/\]$/,""),p=p.shift().split("[").concat(p),h=p.length-1):h=0,2===c.length)if(i=y(c[1]),n&&(i=i&&!isNaN(i)?+i:"undefined"===i?f:o[i]!==f?o[i]:i),h)for(;l<=h;l++)u=""===p[l]?s.length:p[l],s=s[u]=l').hide().insertAfter("body")[0].contentWindow,s=function(){return r(a.document[i][u])},(f=function(e,t){if(e!==t){var n=a.document;n.open().close(),n[i].hash="#"+e}})(r()))}var o,a,f,s,p={};return p.start=function(){if(!o){var a=r();f||n(),function l(){var n=r(),p=s(a);n!==a?(f(a=n,p),e(t).trigger(c)):p!==a&&(t[i][u]=t[i][u].replace(/#.*/,"")+"#"+p),o=setTimeout(l,e[c+"Delay"])}()}},p.stop=function(){a||(o&&clearTimeout(o),o=0)},p}()}(jQuery,this); -------------------------------------------------------------------------------- /swagger-ui/lib/jquery.sieve.js: -------------------------------------------------------------------------------- 1 | (function(){var e;e=jQuery,e.fn.sieve=function(t){var n;return n=function(e){var t,n,r,o;for(o=[],n=0,r=e.length;n",itemSelector:"tbody tr",textSelector:null,toggle:function(e,t){return e.toggle(t)},complete:function(){}},t),i.searchInput||(o=e(i.searchTemplate),i.searchInput=o.find("input"),r.before(o)),i.searchInput.on("keyup.sieve change.sieve",function(){var t,o;return o=n(e(this).val().toLowerCase().split(/\s+/)),t=r.find(i.itemSelector),t.each(function(){var t,n,r,c,l,a,u;for(n=e(this),i.textSelector?(t=n.find(i.textSelector),l=t.text().toLowerCase()):l=n.text().toLowerCase(),r=!0,a=0,u=o.length;a=0);return i.toggle(n,r)}),i.complete()})})}}).call(this); -------------------------------------------------------------------------------- /swagger-ui/lib/jquery.sieve.min.js: -------------------------------------------------------------------------------- 1 | (function(){var e;e=jQuery,e.fn.sieve=function(t){var n;return n=function(e){var t,n,r,o;for(o=[],n=0,r=e.length;r>n;n++)t=e[n],t&&o.push(t);return o},this.each(function(){var r,o,i;return r=e(this),i=e.extend({searchInput:null,searchTemplate:"
",itemSelector:"tbody tr",textSelector:null,toggle:function(e,t){return e.toggle(t)},complete:function(){}},t),i.searchInput||(o=e(i.searchTemplate),i.searchInput=o.find("input"),r.before(o)),i.searchInput.on("keyup.sieve change.sieve",function(){var t,o;return o=n(e(this).val().toLowerCase().split(/\s+/)),t=r.find(i.itemSelector),t.each(function(){var t,n,r,c,l,a,u;for(n=e(this),i.textSelector?(t=n.find(i.textSelector),l=t.text().toLowerCase()):l=n.text().toLowerCase(),r=!0,a=0,u=o.length;u>a;a++)c=o[a],r&&(r=l.indexOf(c)>=0);return i.toggle(n,r)}),i.complete()})})}}).call(this); -------------------------------------------------------------------------------- /swagger-ui/lib/jquery.slideto.min.js: -------------------------------------------------------------------------------- 1 | !function(i){i.fn.slideto=function(o){return o=i.extend({slide_duration:"slow",highlight_duration:3e3,highlight:!0,highlight_color:"#FFFF99"},o),this.each(function(){obj=i(this),i("body").animate({scrollTop:obj.offset().top},o.slide_duration,function(){o.highlight&&i.ui.version&&obj.effect("highlight",{color:o.highlight_color},o.highlight_duration)})})}}(jQuery); -------------------------------------------------------------------------------- /swagger-ui/lib/jquery.wiggle.min.js: -------------------------------------------------------------------------------- 1 | jQuery.fn.wiggle=function(e){var a={speed:50,wiggles:3,travel:5,callback:null},e=jQuery.extend(a,e);return this.each(function(){var a=this,l=(jQuery(this).wrap('
').css("position","relative"),0);for(i=1;i<=e.wiggles;i++)jQuery(this).animate({left:"-="+e.travel},e.speed).animate({left:"+="+2*e.travel},2*e.speed).animate({left:"-="+e.travel},e.speed,function(){l++,jQuery(a).parent().hasClass("wiggle-wrap")&&jQuery(a).parent().replaceWith(a),l==e.wiggles&&jQuery.isFunction(e.callback)&&e.callback()})})}; -------------------------------------------------------------------------------- /swagger-ui/lib/object-assign-pollyfill.js: -------------------------------------------------------------------------------- 1 | "function"!=typeof Object.assign&&!function(){Object.assign=function(n){"use strict";if(void 0===n||null===n)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(n),o=1;o 2 | var qp = null; 3 | if(/code|token|error/.test(window.location.hash)) { 4 | qp = location.hash.substring(1); 5 | } 6 | else { 7 | qp = location.search.substring(1); 8 | } 9 | qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g,'":"') + '"}', 10 | function(key, value) { 11 | return key===""?value:decodeURIComponent(value) } 12 | ):{} 13 | 14 | if (window.opener.swaggerUiAuth.tokenUrl) 15 | window.opener.processOAuthCode(qp); 16 | else 17 | window.opener.onOAuthComplete(qp); 18 | 19 | window.close(); 20 | 21 | -------------------------------------------------------------------------------- /新建文本文档.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jianxuanbing/SwashbuckleEx/a7c0518e3d54248e9f3f63e61d8dc63aab8da81a/新建文本文档.txt --------------------------------------------------------------------------------