From 725a04e17148e33c1466ab3a2da21905e094290e Mon Sep 17 00:00:00 2001 From: Masood Khoshgrd Date: Wed, 5 Jul 2023 15:12:31 +0330 Subject: [PATCH 1/5] Human Friendly Enum in Swagger --- .../Mvc/Json/MvcCoreBuilderExtensions.cs | 2 ++ .../AbpSwaggerGenOptionsExtensions.cs | 5 +++++ .../AbpSwashbuckleDocumentFilter.cs | 16 ++++++++++++++ .../AbpSwashbuckleEnumSchemaFilter.cs | 21 +++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleEnumSchemaFilter.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs index 8c6edd2eb0..b6d17d77b2 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Text.Json; +using System.Text.Json.Serialization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -19,6 +20,7 @@ public static class MvcCoreBuilderExtensions options.JsonSerializerOptions.AllowTrailingCommas = true; options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); + options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); options.JsonSerializerOptions.Converters.Add(new AbpStringToGuidConverter()); options.JsonSerializerOptions.Converters.Add(new AbpNullableStringToGuidConverter()); diff --git a/framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenOptionsExtensions.cs b/framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenOptionsExtensions.cs index 4313041064..240da0fc4e 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenOptionsExtensions.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Microsoft/Extensions/DependencyInjection/AbpSwaggerGenOptionsExtensions.cs @@ -9,4 +9,9 @@ public static class AbpSwaggerGenOptionsExtensions { swaggerGenOptions.DocumentFilter(); } + + public static void UserFriendlyEnums(this SwaggerGenOptions swaggerGenOptions) + { + swaggerGenOptions.SchemaFilter(); + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleDocumentFilter.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleDocumentFilter.cs index dd1b9705b8..3f21df192c 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleDocumentFilter.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleDocumentFilter.cs @@ -28,6 +28,22 @@ public class AbpSwashbuckleDocumentFilter : IDocumentFilter swaggerDoc .Paths .RemoveAll(path => !actionUrls.Contains(path.Key)); + + foreach (OpenApiSchema schema in swaggerDoc.Components.Schemas.Values) + { + ICollection properties = schema.Properties?.Values; + if (properties != null) + { + foreach (OpenApiSchema property in properties) + { + List propertyEnums = property.Enum?.Cast().ToList(); + if (propertyEnums != null && propertyEnums.Any()) + { + property.Description += "

Possible values:
" + string.Join("
", propertyEnums); + } + } + } + } } protected virtual string RemoveRouteParameterConstraints(ActionDescriptor actionDescriptor) diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleEnumSchemaFilter.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleEnumSchemaFilter.cs new file mode 100644 index 0000000000..28f243aa9f --- /dev/null +++ b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleEnumSchemaFilter.cs @@ -0,0 +1,21 @@ +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using System; +using System.Linq; + +namespace Volo.Abp.Swashbuckle; + +public class AbpSwashbuckleEnumSchemaFilter : ISchemaFilter +{ + public void Apply(OpenApiSchema schema, SchemaFilterContext context) + { + if (context.Type.IsEnum) + { + schema.Enum.Clear(); + Enum.GetNames(context.Type) + .ToList() + .ForEach(name => schema.Enum.Add(new OpenApiString($"{name}"))); + } + } +} \ No newline at end of file From 26e23e8c037c8716ef7db4c2f3b9a08639eb3200 Mon Sep 17 00:00:00 2001 From: masoodkhoshgard Date: Mon, 17 Jul 2023 14:49:25 +0330 Subject: [PATCH 2/5] Solving unit test error --- .../Mvc/Json/MvcCoreBuilderExtensions.cs | 2 -- .../Swashbuckle/AbpSwashbuckleDocumentFilter.cs | 16 ---------------- .../AbpSwashbuckleEnumSchemaFilter.cs | 2 ++ 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs index b6d17d77b2..8c6edd2eb0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Text.Json; -using System.Text.Json.Serialization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -20,7 +19,6 @@ public static class MvcCoreBuilderExtensions options.JsonSerializerOptions.AllowTrailingCommas = true; options.JsonSerializerOptions.Converters.Add(new AbpStringToEnumFactory()); - options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); options.JsonSerializerOptions.Converters.Add(new AbpStringToBooleanConverter()); options.JsonSerializerOptions.Converters.Add(new AbpStringToGuidConverter()); options.JsonSerializerOptions.Converters.Add(new AbpNullableStringToGuidConverter()); diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleDocumentFilter.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleDocumentFilter.cs index 162b872d03..d35443f98b 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleDocumentFilter.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleDocumentFilter.cs @@ -28,22 +28,6 @@ public class AbpSwashbuckleDocumentFilter : IDocumentFilter swaggerDoc .Paths .RemoveAll(path => !actionUrls.Contains(path.Key)); - - foreach (OpenApiSchema schema in swaggerDoc.Components.Schemas.Values) - { - ICollection properties = schema.Properties?.Values; - if (properties != null) - { - foreach (OpenApiSchema property in properties) - { - List propertyEnums = property.Enum?.Cast().ToList(); - if (propertyEnums != null && propertyEnums.Any()) - { - property.Description += "

Possible values:
" + string.Join("
", propertyEnums); - } - } - } - } } protected virtual string? RemoveRouteParameterConstraints(ActionDescriptor actionDescriptor) diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleEnumSchemaFilter.cs b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleEnumSchemaFilter.cs index 28f243aa9f..f637fb005e 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleEnumSchemaFilter.cs +++ b/framework/src/Volo.Abp.Swashbuckle/Volo/Abp/Swashbuckle/AbpSwashbuckleEnumSchemaFilter.cs @@ -13,6 +13,8 @@ public class AbpSwashbuckleEnumSchemaFilter : ISchemaFilter if (context.Type.IsEnum) { schema.Enum.Clear(); + schema.Type = nameof(String); + schema.Format = nameof(String); Enum.GetNames(context.Type) .ToList() .ForEach(name => schema.Enum.Add(new OpenApiString($"{name}"))); From 9b0dfed2542a6cd071446a3669621b43f5613bbb Mon Sep 17 00:00:00 2001 From: Salih Date: Tue, 18 Jul 2023 11:35:33 +0300 Subject: [PATCH 3/5] Update en.json --- .../Commercial/Localization/Resources/en.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 07a030ff47..e08ccb877b 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -904,6 +904,8 @@ "DoesTheSubscriptionRenewAutomatically": "Does the subscription renew automatically?", "DoesTheSubscriptionRenewAutomaticallyExplanation": "The ABP Commercial does not have an auto-renewal billing model. Therefore your subscription will not be automatically renewed at the end of your license period. If you want to continue to have the benefits of ABP Commercial, you need to manually renew it at the organization management page. If you have multiple organizations, click the \"Manage\" button at your expiring organization and then click the \"Extend Now\" button to renew your license. You may also want to take a look at the What Happens When My License Ends? section.", "ExtraQuestionCreditsFaqTitle": "Can I purchase extra support question credits?", - "ExtraQuestionCreditsFaqExplanation": "Yes, you can. To buy extra question credits, send an e-mail to info@abp.io with your organization's name. Here's the price list for the extra question credits:
  • 50 questions pack $999
  • 25 questions pack $625
  • 15 questions pack $450
" + "ExtraQuestionCreditsFaqExplanation": "Yes, you can. To buy extra question credits, send an e-mail to info@abp.io with your organization's name. Here's the price list for the extra question credits:
  • 50 questions pack $999
  • 25 questions pack $625
  • 15 questions pack $450
", + "PricingExplanation2": "30 days money back guarantee*. Learn more", + "MoneyBackGuaranteeText": "*30-day money-back guarantee on all licenses! 100% refund on Team, 60% refund on Business within 30 days." } } From 4622880489fa9be041584f5efbee51586f3a523b Mon Sep 17 00:00:00 2001 From: Salih Date: Tue, 18 Jul 2023 13:41:34 +0300 Subject: [PATCH 4/5] Update en.json --- .../Commercial/Localization/Resources/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index e08ccb877b..5b31c7eccb 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -905,7 +905,7 @@ "DoesTheSubscriptionRenewAutomaticallyExplanation": "The ABP Commercial does not have an auto-renewal billing model. Therefore your subscription will not be automatically renewed at the end of your license period. If you want to continue to have the benefits of ABP Commercial, you need to manually renew it at the organization management page. If you have multiple organizations, click the \"Manage\" button at your expiring organization and then click the \"Extend Now\" button to renew your license. You may also want to take a look at the What Happens When My License Ends? section.", "ExtraQuestionCreditsFaqTitle": "Can I purchase extra support question credits?", "ExtraQuestionCreditsFaqExplanation": "Yes, you can. To buy extra question credits, send an e-mail to info@abp.io with your organization's name. Here's the price list for the extra question credits:
  • 50 questions pack $999
  • 25 questions pack $625
  • 15 questions pack $450
", - "PricingExplanation2": "30 days money back guarantee*. Learn more", - "MoneyBackGuaranteeText": "*30-day money-back guarantee on all licenses! 100% refund on Team, 60% refund on Business within 30 days." + "PricingExplanation2": "30 days money back guarantee* . Learn more", + "MoneyBackGuaranteeText": "* 30-day money-back guarantee on all licenses! 100% refund on Team, 60% refund on Business and Enterprise licenses within 30 days." } } From 7600d63620411beae0bedb09141fc9fc7233b5af Mon Sep 17 00:00:00 2001 From: Salih Date: Tue, 18 Jul 2023 13:43:31 +0300 Subject: [PATCH 5/5] Update en.json --- .../AbpIoLocalization/Commercial/Localization/Resources/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 5b31c7eccb..b664ed6421 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -905,7 +905,7 @@ "DoesTheSubscriptionRenewAutomaticallyExplanation": "The ABP Commercial does not have an auto-renewal billing model. Therefore your subscription will not be automatically renewed at the end of your license period. If you want to continue to have the benefits of ABP Commercial, you need to manually renew it at the organization management page. If you have multiple organizations, click the \"Manage\" button at your expiring organization and then click the \"Extend Now\" button to renew your license. You may also want to take a look at the What Happens When My License Ends? section.", "ExtraQuestionCreditsFaqTitle": "Can I purchase extra support question credits?", "ExtraQuestionCreditsFaqExplanation": "Yes, you can. To buy extra question credits, send an e-mail to info@abp.io with your organization's name. Here's the price list for the extra question credits:
  • 50 questions pack $999
  • 25 questions pack $625
  • 15 questions pack $450
", - "PricingExplanation2": "30 days money back guarantee* . Learn more", + "PricingExplanation2": "30 days money back guarantee *. Learn more", "MoneyBackGuaranteeText": "* 30-day money-back guarantee on all licenses! 100% refund on Team, 60% refund on Business and Enterprise licenses within 30 days." } }