From dbea518accb6f2d689a2745a3e564f8b59696825 Mon Sep 17 00:00:00 2001 From: Antonio Lanzolla Date: Fri, 27 Jan 2023 18:29:40 +0100 Subject: [PATCH] #104 - Implemented [Feature request] Use fluent validation rules to define swagger schema #104 --- src/WebUI/ConfigureServices.cs | 28 ++++++- src/WebUI/WebUI.csproj | 15 +++- src/WebUI/nswag.json | 132 ++++++++++++++++----------------- 3 files changed, 103 insertions(+), 72 deletions(-) diff --git a/src/WebUI/ConfigureServices.cs b/src/WebUI/ConfigureServices.cs index 12003e575..572f7daa2 100644 --- a/src/WebUI/ConfigureServices.cs +++ b/src/WebUI/ConfigureServices.cs @@ -1,11 +1,16 @@ -using CleanArchitecture.Application.Common.Interfaces; +using System; +using System.Reflection; +using CleanArchitecture.Application.Common.Interfaces; +using CleanArchitecture.Application.TodoItems.Commands.CreateTodoItem; using CleanArchitecture.Infrastructure.Persistence; using CleanArchitecture.WebUI.Filters; using CleanArchitecture.WebUI.Services; using FluentValidation.AspNetCore; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using NSwag; using NSwag.Generation.Processors.Security; +using ZymLabs.NSwag.FluentValidation; namespace Microsoft.Extensions.DependencyInjection; @@ -24,16 +29,33 @@ public static IServiceCollection AddWebUIServices(this IServiceCollection servic services.AddControllersWithViews(options => options.Filters.Add()) - .AddFluentValidation(x => x.AutomaticValidationEnabled = false); + .AddFluentValidation(x => + { + x.AutomaticValidationEnabled = false; + } + ); services.AddRazorPages(); + services.AddScoped(provider => + { + var validationRules = provider.GetService>(); + var loggerFactory = provider.GetService(); + + return new FluentValidationSchemaProcessor(provider, validationRules, loggerFactory); + }); + // Customise default API behaviour services.Configure(options => options.SuppressModelStateInvalidFilter = true); - services.AddOpenApiDocument(configure => + services.AddOpenApiDocument((configure, serviceProvider) => { + var fluentValidationSchemaProcessor = serviceProvider.CreateScope().ServiceProvider.GetService(); + + // Add the fluent validations schema processor + configure.SchemaProcessors.Add(fluentValidationSchemaProcessor); + configure.Title = "CleanArchitecture API"; configure.AddSecurity("JWT", Enumerable.Empty(), new OpenApiSecurityScheme { diff --git a/src/WebUI/WebUI.csproj b/src/WebUI/WebUI.csproj index ddb738c5c..96ed1d0a6 100644 --- a/src/WebUI/WebUI.csproj +++ b/src/WebUI/WebUI.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -30,11 +30,12 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -44,6 +45,14 @@ + + OnBuildSuccess + + + + + + diff --git a/src/WebUI/nswag.json b/src/WebUI/nswag.json index e4c58e590..e59248db8 100644 --- a/src/WebUI/nswag.json +++ b/src/WebUI/nswag.json @@ -1,5 +1,5 @@ { - "runtime": "Net60", + "runtime": "Net70", "defaultVariables": null, "documentGenerator": { "aspNetCoreToOpenApi": { @@ -59,69 +59,69 @@ "referencePaths": [], "useNuGetCache": false } - }, - "codeGenerators": { - "openApiToTypeScriptClient": { - "className": "{controller}Client", - "moduleName": "", - "namespace": "", - "typeScriptVersion": 4.3, - "template": "Angular", - "promiseType": "Promise", - "httpClass": "HttpClient", - "withCredentials": false, - "useSingletonProvider": true, - "injectionTokenType": "InjectionToken", - "rxJsVersion": 7.0, - "dateTimeType": "Date", - "nullValue": "Undefined", - "generateClientClasses": true, - "generateClientInterfaces": true, - "generateOptionalParameters": false, - "exportTypes": true, - "wrapDtoExceptions": false, - "exceptionClass": "SwaggerException", - "clientBaseClass": null, - "wrapResponses": false, - "wrapResponseMethods": [], - "generateResponseClasses": true, - "responseClass": "SwaggerResponse", - "protectedMethods": [], - "configurationClass": null, - "useTransformOptionsMethod": false, - "useTransformResultMethod": false, - "generateDtoTypes": true, - "operationGenerationMode": "MultipleClientsFromOperationId", - "markOptionalProperties": true, - "generateCloneMethod": false, - "typeStyle": "Class", - "enumStyle": "Enum", - "useLeafType": false, - "classTypes": [], - "extendedClasses": [], - "extensionCode": null, - "generateDefaultValues": true, - "excludedTypeNames": [], - "excludedParameterNames": [], - "handleReferences": false, - "generateConstructorInterface": true, - "convertConstructorInterfaceData": false, - "importRequiredTypes": true, - "useGetBaseUrlMethod": false, - "baseUrlTokenName": "API_BASE_URL", - "queryNullValue": "", - "useAbortSignal": false, - "inlineNamedDictionaries": false, - "inlineNamedAny": false, - "includeHttpContext": false, - "templateDirectory": null, - "typeNameGeneratorType": null, - "propertyNameGeneratorType": null, - "enumNameGeneratorType": null, - "serviceHost": null, - "serviceSchemes": null, - "output": "ClientApp/src/app/web-api-client.ts", - "newLineBehavior": "Auto" - } - } + }//, + //"codeGenerators": { + // "openApiToTypeScriptClient": { + // "className": "{controller}Client", + // "moduleName": "", + // "namespace": "", + // "typeScriptVersion": 4.3, + // "template": "Angular", + // "promiseType": "Promise", + // "httpClass": "HttpClient", + // "withCredentials": false, + // "useSingletonProvider": true, + // "injectionTokenType": "InjectionToken", + // "rxJsVersion": 7.0, + // "dateTimeType": "Date", + // "nullValue": "Undefined", + // "generateClientClasses": false, + // "generateClientInterfaces": false, + // "generateOptionalParameters": false, + // "exportTypes": true, + // "wrapDtoExceptions": false, + // "exceptionClass": "SwaggerException", + // "clientBaseClass": null, + // "wrapResponses": false, + // "wrapResponseMethods": [], + // "generateResponseClasses": true, + // "responseClass": "SwaggerResponse", + // "protectedMethods": [], + // "configurationClass": null, + // "useTransformOptionsMethod": false, + // "useTransformResultMethod": false, + // "generateDtoTypes": true, + // "operationGenerationMode": "MultipleClientsFromOperationId", + // "markOptionalProperties": false, + // "generateCloneMethod": false, + // "typeStyle": "Class", + // "enumStyle": "Enum", + // "useLeafType": false, + // "classTypes": [], + // "extendedClasses": [], + // "extensionCode": null, + // "generateDefaultValues": true, + // "excludedTypeNames": [], + // "excludedParameterNames": [], + // "handleReferences": false, + // "generateConstructorInterface": true, + // "convertConstructorInterfaceData": false, + // "importRequiredTypes": true, + // "useGetBaseUrlMethod": false, + // "baseUrlTokenName": "API_BASE_URL", + // "queryNullValue": "", + // "useAbortSignal": false, + // "inlineNamedDictionaries": false, + // "inlineNamedAny": false, + // "includeHttpContext": false, + // "templateDirectory": null, + // "typeNameGeneratorType": null, + // "propertyNameGeneratorType": null, + // "enumNameGeneratorType": null, + // "serviceHost": null, + // "serviceSchemes": null, + // "output": "ClientApp/src/app/web-api-client.ts", + // "newLineBehavior": "Auto" + // } + //} } \ No newline at end of file