From 69a353e61b6c5a986ed01e5dc01ad0248211b481 Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 23 Aug 2020 16:12:33 +0800 Subject: Add error code to swagger description. --- Timeline/Startup.cs | 5 +- .../DocumentDescriptionDocumentProcessor.cs | 55 ++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 Timeline/Swagger/DocumentDescriptionDocumentProcessor.cs diff --git a/Timeline/Startup.cs b/Timeline/Startup.cs index 86bdaf54..cbca01d0 100644 --- a/Timeline/Startup.cs +++ b/Timeline/Startup.cs @@ -104,6 +104,7 @@ namespace Timeline document.DocumentName = "Timeline"; document.Title = "Timeline REST API Reference"; document.Version = typeof(Startup).Assembly.GetName().Version?.ToString() ?? "unknown version"; + document.DocumentProcessors.Add(new DocumentDescriptionDocumentProcessor()); document.DocumentProcessors.Add( new SecurityDefinitionAppender("JWT", new OpenApiSecurityScheme @@ -111,7 +112,7 @@ namespace Timeline Type = OpenApiSecuritySchemeType.ApiKey, Name = "Authorization", In = OpenApiSecurityApiKeyLocation.Header, - Description = "Type into the textbox: Bearer {your JWT token}." + Description = "Create token via `/api/token/create` ." })); document.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("JWT")); document.OperationProcessors.Add(new DefaultDescriptionOperationProcessor()); @@ -153,7 +154,7 @@ namespace Timeline } app.UseOpenApi(); - app.UseSwaggerUi3(); + app.UseReDoc(); app.UseAuthentication(); app.UseAuthorization(); diff --git a/Timeline/Swagger/DocumentDescriptionDocumentProcessor.cs b/Timeline/Swagger/DocumentDescriptionDocumentProcessor.cs new file mode 100644 index 00000000..dc5ddd96 --- /dev/null +++ b/Timeline/Swagger/DocumentDescriptionDocumentProcessor.cs @@ -0,0 +1,55 @@ +using NSwag.Generation.Processors; +using NSwag.Generation.Processors.Contexts; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Timeline.Models.Http; + +namespace Timeline.Swagger +{ + public class DocumentDescriptionDocumentProcessor : IDocumentProcessor + { + private static Dictionary GetAllErrorCodes() + { + var errorCodes = new Dictionary(); + + void RecursiveCheckErrorCode(Type type) + { + foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) + .Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(int))) + { + var name = (type.FullName + "." + field.Name).Remove(0, typeof(ErrorCodes).FullName!.Length + 1).Replace("+", ".", StringComparison.OrdinalIgnoreCase); + int value = (int)field.GetRawConstantValue()!; + errorCodes.Add(name, value); + } + + foreach (var nestedType in type.GetNestedTypes()) + { + RecursiveCheckErrorCode(nestedType); + } + } + + RecursiveCheckErrorCode(typeof(ErrorCodes)); + + return errorCodes; + } + + public void Process(DocumentProcessorContext context) + { + StringBuilder description = new StringBuilder(); + description.AppendLine("# Error Codes"); + description.AppendLine("name | value"); + description.AppendLine("---- | -----"); + foreach (var (name, value) in GetAllErrorCodes()) + { + description.AppendLine($"`{name}` | `{value}`"); + } + + context.Document.Info.Description = description.ToString(); + } + } +} -- cgit v1.2.3 From 5a821a3e81dfc14c15c70d90e9266d3a163479a9 Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 23 Aug 2020 17:17:04 +0800 Subject: Add produces and consumes . --- Timeline/Controllers/TimelineController.cs | 3 ++- Timeline/Controllers/UserAvatarController.cs | 2 +- Timeline/Helpers/DataCacheHelper.cs | 2 +- Timeline/Startup.cs | 4 ++++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Timeline/Controllers/TimelineController.cs b/Timeline/Controllers/TimelineController.cs index 43178ac6..90b50bbb 100644 --- a/Timeline/Controllers/TimelineController.cs +++ b/Timeline/Controllers/TimelineController.cs @@ -199,7 +199,8 @@ namespace Timeline.Controllers /// If-None-Match header. /// The data. [HttpGet("timelines/{name}/posts/{id}/data")] - [ProducesResponseType(StatusCodes.Status200OK)] + [Produces("image/png", "image/jpeg", "image/gif", "image/webp", "application/json", "text/json")] + [ProducesResponseType(typeof(byte[]), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status304NotModified)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] diff --git a/Timeline/Controllers/UserAvatarController.cs b/Timeline/Controllers/UserAvatarController.cs index 32f63fc6..97c4bdb8 100644 --- a/Timeline/Controllers/UserAvatarController.cs +++ b/Timeline/Controllers/UserAvatarController.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; -using System.IO; using System.Threading.Tasks; using Timeline.Auth; using Timeline.Filters; @@ -46,6 +45,7 @@ namespace Timeline.Controllers /// If-None-Match header. /// Avatar data. [HttpGet("users/{username}/avatar")] + [Produces("image/png", "image/jpeg", "image/gif", "image/webp", "application/json", "text/json")] [ProducesResponseType(typeof(byte[]), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status304NotModified)] [ProducesResponseType(StatusCodes.Status404NotFound)] diff --git a/Timeline/Helpers/DataCacheHelper.cs b/Timeline/Helpers/DataCacheHelper.cs index 574d90b4..1ad69708 100644 --- a/Timeline/Helpers/DataCacheHelper.cs +++ b/Timeline/Helpers/DataCacheHelper.cs @@ -107,7 +107,7 @@ namespace Timeline.Helpers controller.Response.Headers.Add(ETagHeaderKey, eTagValue); controller.Response.Headers.Add(CacheControlHeaderKey, GenerateCacheControlHeaderValue()); - return controller.StatusCode(StatusCodes.Status304NotModified); + return controller.StatusCode(StatusCodes.Status304NotModified, null); } } diff --git a/Timeline/Startup.cs b/Timeline/Startup.cs index cbca01d0..82c231cb 100644 --- a/Timeline/Startup.cs +++ b/Timeline/Startup.cs @@ -1,6 +1,7 @@ using AutoMapper; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -11,6 +12,7 @@ using NSwag; using NSwag.Generation.Processors.Security; using System; using System.ComponentModel; +using System.Net.Mime; using System.Text.Json.Serialization; using Timeline.Auth; using Timeline.Configs; @@ -50,6 +52,8 @@ namespace Timeline { setup.InputFormatters.Add(new StringInputFormatter()); setup.InputFormatters.Add(new BytesInputFormatter()); + setup.Filters.Add(new ConsumesAttribute(MediaTypeNames.Application.Json, "text/json")); + setup.Filters.Add(new ProducesAttribute(MediaTypeNames.Application.Json, "text/json")); setup.UseApiRoutePrefix("api"); }) .AddJsonOptions(options => -- cgit v1.2.3