ABP Framework version: v8.1.0
UI Type: MVC
Database System: MongoDB
Tiered (for MVC) or Auth Server Separated (for Angular): no
I created a new Angular-based project and adjusted the configuration, which resolved some issues. However, when I run abp generate-proxy -t ng, I encounter the following error: "[API Not Available] Request to https://localhost:44378/api/abp/api-definition is unsuccessful. Please double-check the URL in the source project environment and make sure your application is up and running."
The application is indeed running. Is there a way to configure this in a Razor Page project so that it can generate the Angular UI?
27 Answer(s)
-
0
[API Not Available] Request to https://localhost:44378/api/abp/api-definition is unsuccessful
what result if you request to the
https://localhost:44378/api/abp/api-definition
-
0
-
0
it looks no problem
-
0
-
0
-
0
Originally, when I created this Angular project, the endpoint was set to 44334. I later changed it in the environment file to 44378. Do I need to make changes anywhere else as well?
i am getting below error in Audit Logs
[ { "code": null, "message": "Given type () should be instance of System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e (Parameter 'item')", "details": "ArgumentException: Given type () should be instance of System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e (Parameter 'item')\r\nSTACK TRACE: at Volo.Abp.Http.Modeling.ApiTypeNameHelper.GetTypeName(Type type, ITypeList duplicateTypes)\r\n at Volo.Abp.Http.Modeling.PropertyApiDescriptionModel.Create(PropertyInfo propertyInfo)\r\n at System.Linq.Enumerable.WhereSelectArrayIterator`2.ToArray()\r\n at Volo.Abp.Http.Modeling.TypeApiDescriptionModel.Create(Type type)\r\n at Volo.Abp.AspNetCore.Mvc.AspNetCoreApiDescriptionModelProvider.AddCustomTypesToModel(ApplicationApiDescriptionModel applicationModel, Type type)\r\n at Volo.Abp.AspNetCore.Mvc.AspNetCoreApiDescriptionModelProvider.AddCustomTypesToModel(ApplicationApiDescriptionModel applicationModel, Type type)\r\n at Volo.Abp.AspNetCore.Mvc.AspNetCoreApiDescriptionModelProvider.AddCustomTypesToModel(ApplicationApiDescriptionModel applicationModel, Type type)\r\n at Volo.Abp.AspNetCore.Mvc.AspNetCoreApiDescriptionModelProvider.AddCustomTypesToModel(ApplicationApiDescriptionModel applicationModel, Type type)\r\n at Volo.Abp.AspNetCore.Mvc.AspNetCoreApiDescriptionModelProvider.AddCustomTypesToModel(ApplicationApiDescriptionModel applicationModel, MethodInfo method)\r\n at Volo.Abp.AspNetCore.Mvc.AspNetCoreApiDescriptionModelProvider.AddApiDescriptionToModel(ApiDescription apiDescription, ApplicationApiDescriptionModel applicationModel, ApplicationApiDescriptionModelRequestDto input)\r\n at Volo.Abp.AspNetCore.Mvc.AspNetCoreApiDescriptionModelProvider.CreateApiModel(ApplicationApiDescriptionModelRequestDto input)\r\n at Volo.Abp.AspNetCore.Mvc.ApiExploring.AbpApiDefinitionController.Get(ApplicationApiDescriptionModelRequestDto model)\r\n at lambda_method5818(Closure, Object, Object[])\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n--- End of stack trace from previous location ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.
-
0
Hi,
could you share a minimum reproducible project with me? i will check it.
shiwei.liang@volosoft.com
-
0
-
0
Hi,
could you share a minimum reproducible project with me? i will check it. : )
-
0
Hi, It's hard to find the problem in a few minutes.
I guess the problem is related to your DTO property types.
you can override the
IApiDescriptionModelProvider
service and check the logs.public static class ArrayMatcher { public static T[] Match<T>(T[] sourceArray, T[] destinationArray) { var result = new List<T>(); var currentMethodParamIndex = 0; var parentItem = default(T); foreach (var sourceItem in sourceArray) { if (currentMethodParamIndex < destinationArray.Length) { var destinationItem = destinationArray[currentMethodParamIndex]; if (EqualityComparer<T>.Default.Equals(sourceItem, destinationItem)) { parentItem = default; currentMethodParamIndex++; } else { if (parentItem == null) { parentItem = destinationItem; currentMethodParamIndex++; } } } var resultItem = EqualityComparer<T>.Default.Equals(parentItem, default) ? sourceItem : parentItem; result.Add(resultItem!); } return result.ToArray(); } } [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IApiDescriptionModelProvider))] public class MyAspNetCoreApiDescriptionModelProvider : IApiDescriptionModelProvider, ITransientDependency { public ILogger<MyAspNetCoreApiDescriptionModelProvider> Logger { get; set; } private readonly AspNetCoreApiDescriptionModelProviderOptions _options; private readonly IApiDescriptionGroupCollectionProvider _descriptionProvider; private readonly AbpAspNetCoreMvcOptions _abpAspNetCoreMvcOptions; private readonly AbpApiDescriptionModelOptions _modelOptions; public MyAspNetCoreApiDescriptionModelProvider( IOptions<AspNetCoreApiDescriptionModelProviderOptions> options, IApiDescriptionGroupCollectionProvider descriptionProvider, IOptions<AbpAspNetCoreMvcOptions> abpAspNetCoreMvcOptions, IOptions<AbpApiDescriptionModelOptions> modelOptions) { _options = options.Value; _descriptionProvider = descriptionProvider; _abpAspNetCoreMvcOptions = abpAspNetCoreMvcOptions.Value; _modelOptions = modelOptions.Value; Logger = NullLogger<MyAspNetCoreApiDescriptionModelProvider>.Instance; } public ApplicationApiDescriptionModel CreateApiModel(ApplicationApiDescriptionModelRequestDto input) { //TODO: Can cache the model? var model = ApplicationApiDescriptionModel.Create(); foreach (var descriptionGroupItem in _descriptionProvider.ApiDescriptionGroups.Items) { foreach (var apiDescription in descriptionGroupItem.Items) { if (!apiDescription.ActionDescriptor.IsControllerAction()) { continue; } AddApiDescriptionToModel(apiDescription, model, input); } } foreach (var (_, module) in model.Modules) { var controllers = module.Controllers.GroupBy(x => x.Value.Type).ToList(); foreach (var controller in controllers.Where(x => x.Count() > 1)) { var removedController = module.Controllers.RemoveAll(x => x.Value.IsRemoteService && controller.OrderBy(c => c.Value.ControllerGroupName).Skip(1).Contains(x)); foreach (var removed in removedController) { Logger.LogInformation($"The controller named '{removed.Value.Type}' was removed from ApplicationApiDescriptionModel because it same with other controller."); } } } model.NormalizeOrder(); return model; } private void AddApiDescriptionToModel( ApiDescription apiDescription, ApplicationApiDescriptionModel applicationModel, ApplicationApiDescriptionModelRequestDto input) { var controllerType = apiDescription .ActionDescriptor .AsControllerActionDescriptor() .ControllerTypeInfo; var setting = FindSetting(controllerType); var moduleModel = applicationModel.GetOrAddModule( GetRootPath(controllerType, apiDescription.ActionDescriptor, setting), GetRemoteServiceName(controllerType, setting) ); var controllerModel = moduleModel.GetOrAddController( _options.ControllerNameGenerator(controllerType, setting), FindGroupName(controllerType) ?? apiDescription.GroupName, apiDescription.IsRemoteService(), apiDescription.IsIntegrationService(), apiDescription.GetProperty<ApiVersion>()?.ToString(), controllerType, _modelOptions.IgnoredInterfaces ); var method = apiDescription.ActionDescriptor.GetMethodInfo(); var uniqueMethodName = _options.ActionNameGenerator(method); if (controllerModel.Actions.ContainsKey(uniqueMethodName)) { Logger.LogWarning( $"Controller '{controllerModel.ControllerName}' contains more than one action with name '{uniqueMethodName}' for module '{moduleModel.RootPath}'. Ignored: " + method); return; } Logger.LogDebug($"ActionApiDescriptionModel.Create: {controllerModel.ControllerName}.{uniqueMethodName}"); bool? allowAnonymous = null; if (apiDescription.ActionDescriptor.EndpointMetadata.Any(x => x is IAllowAnonymous)) { allowAnonymous = true; } else if (apiDescription.ActionDescriptor.EndpointMetadata.Any(x => x is IAuthorizeData)) { allowAnonymous = false; } var implementFrom = controllerType.FullName; var interfaceType = controllerType.GetInterfaces().FirstOrDefault(i => i.GetMethods().Any(x => x.ToString() == method.ToString())); if (interfaceType != null) { implementFrom = TypeHelper.GetFullNameHandlingNullableAndGenerics(interfaceType); } var actionModel = controllerModel.AddAction( uniqueMethodName, ActionApiDescriptionModel.Create( uniqueMethodName, method, apiDescription.RelativePath!, apiDescription.HttpMethod, GetSupportedVersions(controllerType, method, setting), allowAnonymous, implementFrom ) ); if (input.IncludeTypes) { AddCustomTypesToModel(applicationModel, method); } AddParameterDescriptionsToModel(actionModel, method, apiDescription); } private static List<string> GetSupportedVersions(Type controllerType, MethodInfo method, ConventionalControllerSetting? setting) { var supportedVersions = new List<ApiVersion>(); var mapToAttributes = method.GetCustomAttributes<MapToApiVersionAttribute>().ToArray(); if (mapToAttributes.Any()) { supportedVersions.AddRange( mapToAttributes.SelectMany(a => a.Versions) ); } else { supportedVersions.AddRange( controllerType.GetCustomAttributes<ApiVersionAttribute>().SelectMany(a => a.Versions) ); setting?.ApiVersions.ForEach(supportedVersions.Add); } return supportedVersions.Select(v => v.ToString()).Distinct().ToList(); } private void AddCustomTypesToModel(ApplicationApiDescriptionModel applicationModel, MethodInfo method) { foreach (var parameterInfo in method.GetParameters()) { try { AddCustomTypesToModel(applicationModel, parameterInfo.ParameterType); } catch(Exception e) { Logger.LogError($"Error while adding parameter type to model, method info: {method.Name}, parameter info: {parameterInfo.Name}, parameter type: {parameterInfo.ParameterType.FullName}"); throw e; } } try { AddCustomTypesToModel(applicationModel, method.ReturnType); } catch (Exception e) { Logger.LogError($"Error while adding return type to model, method info: {method.Name}, return type: {method.ReturnType.FullName}"); throw e; } } private static void AddCustomTypesToModel(ApplicationApiDescriptionModel applicationModel, Type? type) { if (type == null) { return; } if (type.IsGenericParameter) { return; } type = AsyncHelper.UnwrapTask(type); if (type == typeof(object) || type == typeof(void) || type == typeof(Enum) || type == typeof(ValueType) || type == typeof(DateOnly) || type == typeof(TimeOnly) || TypeHelper.IsPrimitiveExtended(type)) { return; } if (TypeHelper.IsDictionary(type, out var keyType, out var valueType)) { AddCustomTypesToModel(applicationModel, keyType); AddCustomTypesToModel(applicationModel, valueType); return; } if (TypeHelper.IsEnumerable(type, out var itemType)) { AddCustomTypesToModel(applicationModel, itemType); return; } if (type.IsGenericType && !type.IsGenericTypeDefinition) { var genericTypeDefinition = type.GetGenericTypeDefinition(); AddCustomTypesToModel(applicationModel, genericTypeDefinition); foreach (var genericArgument in type.GetGenericArguments()) { AddCustomTypesToModel(applicationModel, genericArgument); } return; } var typeName = CalculateTypeName(type); if (applicationModel.Types.ContainsKey(typeName)) { return; } applicationModel.Types[typeName] = TypeApiDescriptionModel.Create(type); AddCustomTypesToModel(applicationModel, type.BaseType); foreach (var propertyInfo in type.GetProperties().Where(p => p.DeclaringType == type)) { AddCustomTypesToModel(applicationModel, propertyInfo.PropertyType); } } private static string CalculateTypeName(Type type) { if (!type.IsGenericTypeDefinition) { return TypeHelper.GetFullNameHandlingNullableAndGenerics(type); } var i = 0; var argumentList = type .GetGenericArguments() .Select(_ => "T" + i++) .JoinAsString(","); return $"{type.FullName!.Left(type.FullName!.IndexOf('`'))}<{argumentList}>"; } private void AddParameterDescriptionsToModel(ActionApiDescriptionModel actionModel, MethodInfo method, ApiDescription apiDescription) { if (!apiDescription.ParameterDescriptions.Any()) { return; } var parameterDescriptionNames = apiDescription .ParameterDescriptions .Select(p => p.Name) .ToArray(); var methodParameterNames = method .GetParameters() .Where(IsNotFromServicesParameter) .Select(GetMethodParamName) .ToArray(); var matchedMethodParamNames = ArrayMatcher.Match( parameterDescriptionNames, methodParameterNames ); for (var i = 0; i < apiDescription.ParameterDescriptions.Count; i++) { var parameterDescription = apiDescription.ParameterDescriptions[i]; var matchedMethodParamName = matchedMethodParamNames.Length > i ? matchedMethodParamNames[i] : parameterDescription.Name; actionModel.AddParameter(ParameterApiDescriptionModel.Create( parameterDescription.Name, _options.ApiParameterNameGenerator?.Invoke(parameterDescription), matchedMethodParamName, parameterDescription.Type, parameterDescription.RouteInfo?.IsOptional ?? false, parameterDescription.RouteInfo?.DefaultValue, parameterDescription.RouteInfo?.Constraints?.Select(c => c.GetType().Name).ToArray(), parameterDescription.Source.Id, parameterDescription.ModelMetadata?.ContainerType != null ? parameterDescription.ParameterDescriptor?.Name ?? string.Empty : string.Empty ) ); } } private static bool IsNotFromServicesParameter(ParameterInfo parameterInfo) { return !parameterInfo.IsDefined(typeof(FromServicesAttribute), true); } public string GetMethodParamName(ParameterInfo parameterInfo) { var modelNameProvider = parameterInfo.GetCustomAttributes() .OfType<IModelNameProvider>() .FirstOrDefault(); if (modelNameProvider == null) { return parameterInfo.Name!; } return (modelNameProvider.Name ?? parameterInfo.Name)!; } private static string GetRootPath( [NotNull] Type controllerType, [NotNull] ActionDescriptor actionDescriptor, ConventionalControllerSetting? setting) { if (setting != null) { return setting.RootPath; } var areaAttr = controllerType.GetCustomAttributes().OfType<AreaAttribute>().FirstOrDefault() ?? actionDescriptor.EndpointMetadata.OfType<AreaAttribute>().FirstOrDefault(); if (areaAttr != null) { return areaAttr.RouteValue; } return ModuleApiDescriptionModel.DefaultRootPath; } private string GetRemoteServiceName(Type controllerType, ConventionalControllerSetting? setting) { if (setting != null) { return setting.RemoteServiceName; } var remoteServiceAttr = controllerType.GetCustomAttributes().OfType<RemoteServiceAttribute>().FirstOrDefault(); if (remoteServiceAttr?.Name != null) { return remoteServiceAttr.Name; } return ModuleApiDescriptionModel.DefaultRemoteServiceName; } private string? FindGroupName(Type controllerType) { var controllerNameAttribute = controllerType.GetCustomAttributes().OfType<ControllerNameAttribute>().FirstOrDefault(); if (controllerNameAttribute?.Name != null) { return controllerNameAttribute.Name; } return null; } private ConventionalControllerSetting? FindSetting(Type controllerType) { foreach (var controllerSetting in _abpAspNetCoreMvcOptions.ConventionalControllers.ConventionalControllerSettings) { if (controllerSetting.GetControllerTypes().Contains(controllerType)) { return controllerSetting; } } return null; } }
-
0
I resolved the issue without needing to override the file—although the error message was ambiguous, the logs provided clear insight into the problem.
Now, when I create a new module using yarn ng generate module tickets --route customerService --module app.module, it's generating empty components, and the URL isn't visible in the menu. How do I map the permissions for this? Or is there a different way to generate a complete UI using the ABP CLI?
-
0
it's generating empty components, and the URL isn't visible in the menu. How do I map the permissions for this? Or is there a different way to generate a complete UI using the ABP CLI?
you can use abp suite to generate code.
-
0
it's generating empty components, and the URL isn't visible in the menu. How do I map the permissions for this? Or is there a different way to generate a complete UI using the ABP CLI?
you can use abp suite to generate code.
ABP Suite generates the UI only for Razor Pages since the original project is based on Razor Pages. I copied this Angular project from a new project and configured it to work with the Razor Pages backend APIs. Is there any configuration file I can modify so that ABP Suite will generate Angular UIs instead?
-
0
-
0
-
0
%UserProfile%\.abp\suite
-
0
-
0
The ng directory is incorrect .
you can create a new ng project with suite to check what's the path config
-
0
It's the same, but it's still not working. Could this be because the host project URL is set to null?
-
0
you can check the new project settings.
-
0
Can I mail you the file? Maybe you can spot the difference and help figure out what's going wrong.
-
0
okay
-
0
-
0
-
0
could you share the suite logs?