From 224494d0aa0a47612b6d98d1ff884bd8011274b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 20 Nov 2019 16:22:51 +0300 Subject: [PATCH] Revised api description model. --- .../AbpApiDefinitionController.cs | 4 +- .../AspNetCoreApiDescriptionModelProvider.cs | 21 ++- .../DynamicProxying/ApiDescriptionFinder.cs | 2 +- ...pplicationApiDescriptionModelRequestDto.cs | 7 + .../Modeling/ControllerApiDescriptionModel.cs | 8 +- .../ControllerInterfaceApiDescriptionModel.cs | 4 +- .../Modeling/IApiDescriptionModelProvider.cs | 2 +- .../MethodParameterApiDescriptionModel.cs | 7 +- .../Abp/Http/Modeling/ModelingTypeHelper.cs | 127 ++++++++++++++++++ .../Modeling/ParameterApiDescriptionModel.cs | 7 +- .../Modeling/PropertyApiDescriptionModel.cs | 7 +- .../ReturnValueApiDescriptionModel.cs | 9 +- .../Http/Modeling/TypeApiDescriptionModel.cs | 4 +- .../JQuery/JQueryProxyScriptGenerator.cs | 4 +- .../Http/ProxyScripting/ProxyScriptManager.cs | 2 +- 15 files changed, 185 insertions(+), 30 deletions(-) create mode 100644 framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ApplicationApiDescriptionModelRequestDto.cs create mode 100644 framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ModelingTypeHelper.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpApiDefinitionController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpApiDefinitionController.cs index ae72975486..e1c2d1f859 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpApiDefinitionController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApiExploring/AbpApiDefinitionController.cs @@ -14,9 +14,9 @@ namespace Volo.Abp.AspNetCore.Mvc.ApiExploring } [HttpGet] - public ApplicationApiDescriptionModel Get() + public ApplicationApiDescriptionModel Get(ApplicationApiDescriptionModelRequestDto model) { - return _modelProvider.CreateApiModel(); + return _modelProvider.CreateApiModel(model); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs index 696860734f..f7b7d6fcae 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Volo.Abp.Application.Services; +using Volo.Abp.AspNetCore.Mvc.ApiExploring; using Volo.Abp.AspNetCore.Mvc.Conventions; using Volo.Abp.AspNetCore.Mvc.Utils; using Volo.Abp.DependencyInjection; @@ -42,7 +43,7 @@ namespace Volo.Abp.AspNetCore.Mvc Logger = NullLogger.Instance; } - public ApplicationApiDescriptionModel CreateApiModel() + public ApplicationApiDescriptionModel CreateApiModel(ApplicationApiDescriptionModelRequestDto input) { //TODO: Can cache the model? @@ -57,14 +58,17 @@ namespace Volo.Abp.AspNetCore.Mvc continue; } - AddApiDescriptionToModel(apiDescription, model); + AddApiDescriptionToModel(apiDescription, model, input); } } return model; } - private void AddApiDescriptionToModel(ApiDescription apiDescription, ApplicationApiDescriptionModel applicationModel) + private void AddApiDescriptionToModel( + ApiDescription apiDescription, + ApplicationApiDescriptionModel applicationModel, + ApplicationApiDescriptionModelRequestDto input) { var controllerType = apiDescription.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(); var setting = FindSetting(controllerType); @@ -92,7 +96,10 @@ namespace Volo.Abp.AspNetCore.Mvc GetSupportedVersions(controllerType, method, setting) )); - AddCustomTypesToModel(applicationModel, method); + if (input.IncludeTypes) + { + AddCustomTypesToModel(applicationModel, method); + } AddParameterDescriptionsToModel(actionModel, method, apiDescription); } @@ -199,15 +206,15 @@ namespace Volo.Abp.AspNetCore.Mvc /* TODO: Add interfaces */ - var typeAsString = type.FullName; + var typeName = ModelingTypeHelper.GetFullNameHandlingNullableAndGenerics(type); - if (applicationModel.Types.ContainsKey(typeAsString)) + if (applicationModel.Types.ContainsKey(typeName)) { return; } var typeModel = TypeApiDescriptionModel.Create(type); - applicationModel.Types[typeAsString] = typeModel; + applicationModel.Types[typeName] = typeModel; AddCustomTypesToModel(applicationModel, type.BaseType); diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs index fe6192fd85..4ed9b41e10 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs @@ -57,7 +57,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying for (int i = 0; i < methodParameters.Length; i++) { - if (action.ParametersOnMethod[i].TypeAsString != methodParameters[i].ParameterType.FullName) + if (action.ParametersOnMethod[i].Type != ModelingTypeHelper.GetFullNameHandlingNullableAndGenerics(methodParameters[i].ParameterType)) { found = false; break; diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ApplicationApiDescriptionModelRequestDto.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ApplicationApiDescriptionModelRequestDto.cs new file mode 100644 index 0000000000..bb50fc0d96 --- /dev/null +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ApplicationApiDescriptionModelRequestDto.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Http.Modeling +{ + public class ApplicationApiDescriptionModelRequestDto + { + public bool IncludeTypes { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ControllerApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ControllerApiDescriptionModel.cs index dfad32f621..db5a5eb37a 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ControllerApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ControllerApiDescriptionModel.cs @@ -10,7 +10,7 @@ namespace Volo.Abp.Http.Modeling { public string ControllerName { get; set; } - public string TypeAsString { get; set; } + public string Type { get; set; } public List Interfaces { get; set; } @@ -26,7 +26,7 @@ namespace Volo.Abp.Http.Modeling return new ControllerApiDescriptionModel { ControllerName = controllerName, - TypeAsString = type.FullName, + Type = type.FullName, Actions = new Dictionary(), Interfaces = type .GetInterfaces() @@ -52,7 +52,7 @@ namespace Volo.Abp.Http.Modeling { var subModel = new ControllerApiDescriptionModel { - TypeAsString = TypeAsString, + Type = Type, Interfaces = Interfaces, ControllerName = ControllerName, Actions = new Dictionary() @@ -71,7 +71,7 @@ namespace Volo.Abp.Http.Modeling public bool Implements(Type interfaceType) { - return Interfaces.Any(i => i.TypeAsString == interfaceType.FullName); + return Interfaces.Any(i => i.Type == interfaceType.FullName); } public override string ToString() diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ControllerInterfaceApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ControllerInterfaceApiDescriptionModel.cs index 3868ec94f9..04b5ea1bc9 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ControllerInterfaceApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ControllerInterfaceApiDescriptionModel.cs @@ -5,7 +5,7 @@ namespace Volo.Abp.Http.Modeling [Serializable] public class ControllerInterfaceApiDescriptionModel { - public string TypeAsString { get; set; } + public string Type { get; set; } private ControllerInterfaceApiDescriptionModel() { @@ -16,7 +16,7 @@ namespace Volo.Abp.Http.Modeling { return new ControllerInterfaceApiDescriptionModel { - TypeAsString = type.FullName + Type = type.FullName }; } } diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/IApiDescriptionModelProvider.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/IApiDescriptionModelProvider.cs index 800dc504db..6f8803ddb6 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/IApiDescriptionModelProvider.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/IApiDescriptionModelProvider.cs @@ -2,6 +2,6 @@ namespace Volo.Abp.Http.Modeling { public interface IApiDescriptionModelProvider { - ApplicationApiDescriptionModel CreateApiModel(); + ApplicationApiDescriptionModel CreateApiModel(ApplicationApiDescriptionModelRequestDto input); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/MethodParameterApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/MethodParameterApiDescriptionModel.cs index fdc50090d2..47145adaaf 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/MethodParameterApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/MethodParameterApiDescriptionModel.cs @@ -8,7 +8,9 @@ namespace Volo.Abp.Http.Modeling { public string Name { get; set; } - public string TypeAsString { get; set; } + public string Type { get; set; } + + public string TypeSimple { get; set; } public bool IsOptional { get; set; } @@ -24,7 +26,8 @@ namespace Volo.Abp.Http.Modeling return new MethodParameterApiDescriptionModel { Name = parameterInfo.Name, - TypeAsString = parameterInfo.ParameterType.FullName, + Type = ModelingTypeHelper.GetFullNameHandlingNullableAndGenerics(parameterInfo.ParameterType), + TypeSimple = ModelingTypeHelper.GetSimplifiedName(parameterInfo.ParameterType), IsOptional = parameterInfo.IsOptional, DefaultValue = parameterInfo.HasDefaultValue ? parameterInfo.DefaultValue : null }; diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ModelingTypeHelper.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ModelingTypeHelper.cs new file mode 100644 index 0000000000..2d4b2bac85 --- /dev/null +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ModelingTypeHelper.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using JetBrains.Annotations; + +namespace Volo.Abp.Http.Modeling +{ + public static class ModelingTypeHelper + { + public static string GetFullNameHandlingNullableAndGenerics([NotNull] Type type) + { + Check.NotNull(type, nameof(type)); + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + return type.GenericTypeArguments[0].FullName + "?"; + } + + if (type.IsGenericType) + { + var genericType = type.GetGenericTypeDefinition(); + return $"{genericType.FullName.Left(genericType.FullName.IndexOf('`'))}<{type.GenericTypeArguments.Select(GetFullNameHandlingNullableAndGenerics).JoinAsString(",")}>"; + } + + return type.FullName; + } + + public static string GetSimplifiedName([NotNull] Type type) + { + Check.NotNull(type, nameof(type)); + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + return GetSimplifiedName(type.GenericTypeArguments[0]) + "?"; + } + + if (type.IsGenericType) + { + var genericType = type.GetGenericTypeDefinition(); + return $"{genericType.FullName.Left(genericType.FullName.IndexOf('`'))}<{type.GenericTypeArguments.Select(GetSimplifiedName).JoinAsString(",")}>"; + } + + if (type == typeof(string)) + { + return "string"; + } + else if (type == typeof(int)) + { + return "number"; + } + else if (type == typeof(long)) + { + return "number"; + } + else if (type == typeof(bool)) + { + return "boolean"; + } + else if (type == typeof(char)) + { + return "string"; + } + else if (type == typeof(double)) + { + return "number"; + } + else if (type == typeof(float)) + { + return "number"; + } + else if (type == typeof(decimal)) + { + return "number"; + } + else if (type == typeof(DateTime)) + { + return "string"; + } + else if (type == typeof(DateTimeOffset)) + { + return "string"; + } + else if (type == typeof(TimeSpan)) + { + return "string"; + } + else if (type == typeof(Guid)) + { + return "string"; + } + else if (type == typeof(byte)) + { + return "number"; + } + else if (type == typeof(sbyte)) + { + return "number"; + } + else if (type == typeof(short)) + { + return "number"; + } + else if (type == typeof(ushort)) + { + return "number"; + } + else if (type == typeof(uint)) + { + return "number"; + } + else if (type == typeof(ulong)) + { + return "number"; + } + else if (type == typeof(IntPtr)) + { + return "number"; + } + else if (type == typeof(UIntPtr)) + { + return "number"; + } + + return type.FullName; + } + } +} diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ParameterApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ParameterApiDescriptionModel.cs index e05e36aec3..c984de48de 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ParameterApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ParameterApiDescriptionModel.cs @@ -9,7 +9,9 @@ namespace Volo.Abp.Http.Modeling public string Name { get; set; } - public string TypeAsString { get; set; } + public string Type { get; set; } + + public string TypeSimple { get; set; } public bool IsOptional { get; set; } @@ -30,7 +32,8 @@ namespace Volo.Abp.Http.Modeling { Name = name, NameOnMethod = nameOnMethod, - TypeAsString = type?.FullName, + Type = type != null ? ModelingTypeHelper.GetFullNameHandlingNullableAndGenerics(type) : null, + TypeSimple = type != null ? ModelingTypeHelper.GetSimplifiedName(type) : null, IsOptional = isOptional, DefaultValue = defaultValue, ConstraintTypes = constraintTypes, diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs index ee39f54687..8c6ea9e678 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/PropertyApiDescriptionModel.cs @@ -8,7 +8,9 @@ namespace Volo.Abp.Http.Modeling { public string Name { get; set; } - public string TypeAsString { get; set; } + public string Type { get; set; } + + public string TypeSimple { get; set; } //TODO: Validation rules for this property public static PropertyApiDescriptionModel Create(PropertyInfo propertyInfo) @@ -16,7 +18,8 @@ namespace Volo.Abp.Http.Modeling return new PropertyApiDescriptionModel { Name = propertyInfo.Name, - TypeAsString = propertyInfo.PropertyType.FullName + Type = ModelingTypeHelper.GetFullNameHandlingNullableAndGenerics(propertyInfo.PropertyType), + TypeSimple = ModelingTypeHelper.GetSimplifiedName(propertyInfo.PropertyType) }; } } diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ReturnValueApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ReturnValueApiDescriptionModel.cs index 78bd5982fe..d6532be6d4 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ReturnValueApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ReturnValueApiDescriptionModel.cs @@ -6,7 +6,9 @@ namespace Volo.Abp.Http.Modeling [Serializable] public class ReturnValueApiDescriptionModel { - public string TypeAsString { get; set; } + public string Type { get; set; } + + public string TypeSimple { get; set; } private ReturnValueApiDescriptionModel() { @@ -15,9 +17,12 @@ namespace Volo.Abp.Http.Modeling public static ReturnValueApiDescriptionModel Create(Type type) { + var unwrappedType = AsyncHelper.UnwrapTask(type); + return new ReturnValueApiDescriptionModel { - TypeAsString = AsyncHelper.UnwrapTask(type).FullName + Type = ModelingTypeHelper.GetFullNameHandlingNullableAndGenerics(unwrappedType), + TypeSimple = ModelingTypeHelper.GetSimplifiedName(unwrappedType) }; } } diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/TypeApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/TypeApiDescriptionModel.cs index 65f7a61b27..fcc4b034ea 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/TypeApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/TypeApiDescriptionModel.cs @@ -6,7 +6,7 @@ namespace Volo.Abp.Http.Modeling [Serializable] public class TypeApiDescriptionModel { - public string BaseTypeAsString { get; set; } + public string BaseType { get; set; } public bool IsEnum { get; set; } @@ -32,7 +32,7 @@ namespace Volo.Abp.Http.Modeling var typeModel = new TypeApiDescriptionModel { IsEnum = type.IsEnum, - BaseTypeAsString = baseType?.FullName + BaseType = baseType != null ? ModelingTypeHelper.GetFullNameHandlingNullableAndGenerics(baseType) : null }; if (typeModel.IsEnum) diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Generators/JQuery/JQueryProxyScriptGenerator.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Generators/JQuery/JQueryProxyScriptGenerator.cs index 4cf80f7ed8..fd9a79c006 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Generators/JQuery/JQueryProxyScriptGenerator.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Generators/JQuery/JQueryProxyScriptGenerator.cs @@ -56,7 +56,7 @@ namespace Volo.Abp.Http.ProxyScripting.Generators.JQuery private static void AddControllerScript(StringBuilder script, ControllerApiDescriptionModel controller) { - var controllerName = GetNormalizedTypeName(controller.TypeAsString); + var controllerName = GetNormalizedTypeName(controller.Type); script.AppendLine($" // controller {controllerName}"); script.AppendLine(); @@ -125,7 +125,7 @@ namespace Volo.Abp.Http.ProxyScripting.Generators.JQuery script.AppendLine(" url: abp.appPath + '" + ProxyScriptingHelper.GenerateUrlWithParameters(action) + "',"); script.Append(" type: '" + httpMethod + "'"); - if (action.ReturnValue.TypeAsString == typeof(void).FullName) + if (action.ReturnValue.Type == typeof(void).FullName) { script.AppendLine(","); script.Append(" dataType: null"); diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/ProxyScriptManager.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/ProxyScriptManager.cs index 1b89de2b3a..68ef7aee5d 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/ProxyScriptManager.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/ProxyScriptManager.cs @@ -48,7 +48,7 @@ namespace Volo.Abp.Http.ProxyScripting private string CreateScript(ProxyScriptingModel scriptingModel) { - var apiModel = _modelProvider.CreateApiModel(); + var apiModel = _modelProvider.CreateApiModel(new ApplicationApiDescriptionModelRequestDto {IncludeTypes = false}); if (scriptingModel.IsPartialRequest()) {