Unable to load the service index for source .../nuget/v3/index.json
So the fix is to make NuGet not use that unreachable Azure DevOps feed for Studio/Suite operations.
Disable or remove this source from NuGet config:
https://pkgs.dev.azure.com/treva-marketplace-platform/_packaging/TavTechnologies.Treva/nuget/v3/index.json
Where to do it (do all that apply):
A. Global/user NuGet.Config
%AppData%\NuGet\NuGet.ConfigC:\Program Files (x86)\NuGet\Config\*.configC:\ProgramData\NuGet\Config\*.configB. Repo-level NuGet.Config
NuGet.Config and check if that feed is defined there too.C. Visual Studio NuGet sources
After disabling/removing it, run in a terminal:
dotnet nuget list source
dotnet nuget locals all --clear
Restart ABP Studio and try “fetch versions” again.
Create a NuGet.Config that only contains public sources (nuget.org) and make Studio/CLI use it.
Example minimal config (save somewhere like C:\Temp\abp-nuget-only-nugetorg.config):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
Then use that config when you install/update the Studio CLI (the part that typically fails when feeds are broken):
dotnet tool update -g Volo.Abp.Studio.Cli --configfile C:\Temp\abp-nuget-only-nugetorg.config
Once Studio can successfully manage its CLI and version mapping, you can return to the original “SuiteTemplates template missing” issue (version mismatch / stale build outputs).
This is the same pattern as an ABP Studio CLI install failure caused by an unreachable company NuGet feed; removing it fixed the issue:
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
ABP Studio / Suite is trying to query available Suite versions via NuGet, but on your machine NuGet restore is configured with a feed that is currently unreachable:
https://pkgs.dev.azure.com/treva-marketplace-platform/_packaging/TavTechnologies.Treva/nuget/v3/index.json
When that feed is down / blocked (VPN, proxy, credentials), NuGet operations fail, and Studio can’t fetch the version list.
Do this:
Fix or disable the failing NuGet source
%AppData%\NuGet\NuGet.Config (Windows user-level)NuGet.Config in your solution / repo (if you have one)Workaround: install the Suite version explicitly (no “fetch versions” UI needed) Run this in a terminal (same user that runs Studio/Suite):
abp suite install --version 10.2.0
# or update to an explicit version
abp suite update --version 10.2.0
Then run:
abp suite
abp logout
abp login
Volo.Abp.Commercial.SuiteTemplates versionbin/obj and rebuild the solution(Verified)
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Volo.Abp.Commercial.SuiteTemplates that matches your installed ABP Suite version, or when your solution output still contains old assemblies (common after upgrading from 9.x to 10.x).Do the following in order (this fully fixes the “template missing …ApplicationMapperlyMapper_Usings.txt” class of errors):
Make ABP Suite version match your solution (10.2.x)
Ensure Volo.Abp.Commercial.SuiteTemplates version matches the Suite version
Volo.Abp.Commercial.SuiteTemplates and make sure the version is exactly the same as the ABP Suite version you’re running (not just “10.x”, but the exact patch line).Hard clean the solution outputs (removes stale 9.x assemblies)
bin and obj folders under the entire solution (all microservices and shared projects).Build the solution (Suite requires a recent build)
If you migrated to Mapperly: keep Suite-managed mapper files “clean”
ApplicationMapperly..., you are on the Mapperly path. Keep the conventional, Suite-managed files in ObjectMapping (like *ApplicationMappers.cs) reserved for Suite updates.This is why having an ObjectMapping/SettingServiceApplicationMappers file is fine, but if there are extra/misnamed files or stale builds, Suite may not resolve the expected template-to-file conventions correctly.
Links (verified):
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Recommended approach (tenant-based validation with single LDAP):
__tenant, subdomain, etc.).In ABP, the cleanest place to do this for the interactive OpenIddict login is to override the login page model and inject your LDAP check there, right before calling the base sign-in logic.
Where to intervene in the OpenIddict login flow:
/Account/Login), intervene in the Account login page post handler (i.e., in a custom LoginModel override) before the framework completes the sign-in and OpenIddict proceeds to generate the authorization response.AuthorizeController in your project, and you can check authentication state with:var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
(This is useful when you need to enforce extra rules during `/connect/authorize`.)
Source: ABP support answer for overriding authorize flow. (link below)
How to ensure host (super admin) login remains exempt:
CurrentTenant.Id == null (host side), skip the LDAP Unit/Org-to-tenant validation entirely.CurrentTenant.Id != null (tenant side).Minimal implementation outline (custom login page model):
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.Account.Web;
using Volo.Abp.Account.Web.Pages.Account;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
public class LdapTenantRestrictedLoginModel : LoginModel, ITransientDependency
{
private readonly ICurrentTenant _currentTenant;
private readonly ILdapUnitResolver _ldapUnitResolver; // your service
private readonly ITenantUnitMapping _tenantUnitMapping; // your service
public LdapTenantRestrictedLoginModel(
IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions,
IOptions<Microsoft.AspNetCore.Identity.IdentityOptions> identityOptions,
IdentityDynamicClaimsPrincipalContributorCache contributorCache,
ICurrentTenant currentTenant,
ILdapUnitResolver ldapUnitResolver,
ITenantUnitMapping tenantUnitMapping)
: base(schemeProvider, accountOptions, identityOptions, contributorCache)
{
_currentTenant = currentTenant;
_ldapUnitResolver = ldapUnitResolver;
_tenantUnitMapping = tenantUnitMapping;
}
public override async Task<IActionResult> OnPostAsync(string action)
{
// Host login is exempt
if (_currentTenant.Id != null)
{
// 1) Validate credentials + resolve unit from LDAP (implementation is yours)
var unit = await _ldapUnitResolver.ResolveUnitAsync(
LoginInput.UserNameOrEmailAddress,
LoginInput.Password
);
// 2) Compare unit to current tenant
var expectedUnit = await _tenantUnitMapping.GetUnitForTenantAsync(_currentTenant.Id.Value);
if (unit != expectedUnit)
{
Alerts.Danger("You are not allowed to sign in to this tenant.");
return Page();
}
}
// Continue with the normal ABP login flow (cookies/OpenIddict)
return await base.OnPostAsync(action);
}
}
Register it by creating a page override in your host project under Pages/Account/Login.cshtml.cs (same razor page route) so ABP uses your model for /Account/Login.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
UseSqlite(...) (connection string / options) and it doesn’t automatically set WAL, busy_timeout, cache_size, etc.Microsoft.Data.Sqlite supports many PRAGMAs via connection string keywords. In an ABP app, this means you can set them in appsettings.json:
{
"ConnectionStrings": {
"Default": "Data Source=app.db;Cache=Shared;Pooling=True;Foreign Keys=True;Journal Mode=WAL;Synchronous=Normal;Busy Timeout=5000"
}
}
Then ABP/EF Core will use it as usual (your existing UseSqlite(configuration.GetConnectionString("Default"))).
Notes:
If you need PRAGMAs like mmap_size, cache_size, journal_size_limit reliably, run raw SQL PRAGMA statements right after the connection opens. The simplest ABP-friendly place is your DbContext:
using Microsoft.EntityFrameworkCore;
public class MyDbContext : AbpDbContext<MyDbContext>
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options)
{
// Ensure PRAGMAs are set when DbContext is created
Database.OpenConnection();
// Apply PRAGMAs
Database.ExecuteSqlRaw("PRAGMA journal_mode = WAL;");
Database.ExecuteSqlRaw("PRAGMA synchronous = NORMAL;");
Database.ExecuteSqlRaw("PRAGMA mmap_size = 134217728;");
Database.ExecuteSqlRaw("PRAGMA cache_size = 2000;");
Database.ExecuteSqlRaw("PRAGMA busy_timeout = 5000;");
Database.ExecuteSqlRaw("PRAGMA foreign_keys = ON;");
Database.ExecuteSqlRaw("PRAGMA journal_size_limit = 67108864;");
}
}
Important:
PRAGMA journal_mode=WAL and similar settings are connection-level / database-level behaviors; ensure they’re applied consistently for all app instances.You can implement an EF Core DbConnectionInterceptor that runs PRAGMAs on ConnectionOpened and register it in your module where you configure AbpDbContextOptions. This avoids putting it into the DbContext constructor and makes it easier to reuse across multiple DbContexts.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
/api/abp/application-configuration is expected to be called right after login (Angular/MVC UIs use it to bootstrap current user, settings, features, permissions, etc.). When this endpoint is slow, it’s almost always because one (or more) of the contributors behind it is doing expensive work (typically: permission/policy resolution, settings retrieval, or any custom IApplicationConfigurationContributor you added), or because the app is doing “first request” warm-up work (cold start, DB connection pool warmup, etc.).Enable detailed timing on the server to see where time is spent for that single request:
Turn on ABP/Microsoft logs at least for the configuration pipeline categories in your AuthServer/Host:
Volo.Abp.AspNetCore.Mvc.ApplicationConfigurationsVolo.Abp.AuthorizationVolo.Abp.SettingsVolo.Abp.FeatureManagement (if enabled)Microsoft.EntityFrameworkCore.Database.Command (to catch slow SQL)Reproduce login once and inspect the logs for:
This step is the fastest way to get a definitive root cause because the endpoint itself is just an “aggregator”.
A) Granted policies (permissions) computation is slow
application-configuration returns auth.grantedPolicies. If you have:
Fix approaches:
PermissionValueProvider implementations.B) Settings retrieval is slow (especially if stored in DB) If you heavily use Setting Management and many modules/settings are enabled, the endpoint reads a large settings set.
Fix approaches:
C) Cold start / first request after deployment If the first login after an idle period is slow but subsequent ones are fast, it’s typically:
Fix approaches:
D) Reverse proxy / gateway adds latency
In tiered or microservice setups, application-configuration may be proxied through gateways. This can add:
Fix approaches:
auth.grantedPolicies is huge:
auth.grantedPolicies contains many entries, permission resolution is a prime suspect.This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
You can reuse your Blazor UI code only if it’s real Blazor components (Razor .razor files) and not tied to WebAssembly hosting specifics.
In practice, this means you can move/share pages/components into a shared Razor Class Library (RCL) and then use them from a .NET MAUI Blazor Hybrid app.
ABP does not provide an “official template/feature” that automatically turns an ABP Blazor Web App UI into a MAUI Blazor Hybrid app without work. You’ll need to create a MAUI client and integrate it (auth + API consumption), then reference your shared UI components.
Important constraint: If your “Blazor Web App” is ABP’s Blazor WebAssembly UI (with ABP’s WASM theme/components), it usually won’t be a drop-in reuse in MAUI. You typically can still reuse pure Razor components/pages, but you may need to adapt:
Extract reusable UI into a shared project
MyCompany.MyApp.Ui.Shared.Create a .NET MAUI Blazor Hybrid app
Consume your existing ABP backend from MAUI (typical ABP way)
Implement login/token handling for MAUI
These show how to build a MAUI client that consumes an ABP application (auth + client proxies), which is the core missing piece when moving from web UI to MAUI:
Also relevant ABP support discussion about MAUI Blazor hybrid direction + sample:
https://abp.io/support/questions/3640
https://github.com/hikalkan/maui-abp-playing
https://community.abp.io/posts/integrating-maui-client-via-using-openid-connect-aqjjwsdf
ABP UI options (shows MAUI is a UI option in ABP ecosystem, but not “reuse web UI automatically”):
https://abp.io/docs/latest/framework/ui/
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
The ?* you see in the client log is just ABP’s log formatting (it hides the query details). The real proof is on the target service side: earlier you already captured a request arriving as:
/api/abp/application-localization?CultureName=&OnlyDynamics=True&api-version=1.0
So the query parameter exists but ends up empty (CultureName=). That usually happens when the UI app can’t determine the current culture at startup inside the container, so it passes an empty string to the application-localization call.
The most reliable, ABP-consistent fix is: set the default culture explicitly in the UI apps and ensure ABP uses it.
In Program.cs of TavTechnologies.Treva.Web.Public and TavTechnologies.Treva.Web (before app.InitializeApplicationAsync()), add:
using System.Globalization;
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en");
This guarantees CultureInfo.CurrentUICulture.Name is never empty in the process (container) even before the first HTTP request is fully processed.
Keep/configure RequestLocalizationOptions as well (module ConfigureServices):
context.Services.Configure<RequestLocalizationOptions>(options =>
{
options.SetDefaultCulture("en");
});
When .NET runs with invariant globalization, cultures can behave unexpectedly. In your PublicWeb/Web container, ensure this env var is not true:
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false(If it’s missing, that’s fine; just don’t set it to true.)
ABP’s application-localization endpoint requires cultureName (validated by ABP and documented). Your backend logs showed CultureName=. The only way that happens is: the caller (MVC UI) is constructing the request with an empty culture value. For containerized deployments, explicitly setting DefaultThreadCurrentUICulture is the most deterministic way to prevent an empty culture during early startup.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Your log still shows the MVC UI is calling:
GET http://treva-publicgateway/api/abp/application-localization?*
So the UI-side override you added is not being used at all (otherwise you would see cultureName=... on the outgoing request).
The most definitive way to fix this without relying on the UI client pipeline is to make the gateway always supply a default cultureName when it proxies /api/abp/application-localization.
In PublicWebGateway (YARP-based gateway), add a transform for the /api/abp/application-localization route so that if cultureName is missing, it is added.
Example (in the gateway module ConfigureServices):
using Microsoft.Extensions.DependencyInjection;
using System;
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddReverseProxy()
.AddTransforms(builderContext =>
{
// Apply only for the app-localization endpoint
if (builderContext.Route?.Match?.Path != null &&
builderContext.Route.Match.Path.Contains("/api/abp/application-localization", StringComparison.OrdinalIgnoreCase))
{
builderContext.AddRequestTransform(transformContext =>
{
var query = transformContext.HttpContext.Request.Query;
// If cultureName is missing or empty, force a default
if (!query.ContainsKey("cultureName") || string.IsNullOrWhiteSpace(query["cultureName"]))
{
var original = transformContext.ProxyRequest.RequestUri;
// Append required query string parameters
var separator = string.IsNullOrEmpty(original!.Query) ? "?" : "&";
var newUri = new Uri(original.ToString() + $"{separator}cultureName=en&onlyDynamics=true");
transformContext.ProxyRequest.RequestUri = newUri;
}
return ValueTask.CompletedTask;
});
}
});
}
This guarantees the downstream service receives a valid request like:
/api/abp/application-localization?cultureName=en&onlyDynamics=true
and prevents the startup crash.
cultureName.?*, meaning the UI override isn’t actually active (wrong service replaced, wrong project/module, or not loaded).cultureName is required for /api/abp/application-localization:
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
The key detail in your new log is this:
GET http://treva-publicgateway/api/abp/application-localization?*
That means the MVC UI is calling the endpoint without cultureName at all (not even empty). ABP’s /api/abp/application-localization endpoint requires cultureName, so the gateway correctly returns 400, and the UI crashes while building request localization options.
Since you already tried proxy/header/default culture ideas and nothing changed, the most reliable fix is to force the MVC UI to always include cultureName when requesting application-localization by overriding the client that makes that call.
In both TavTechnologies.Treva.Web and TavTechnologies.Treva.Web.Public:
using System.Globalization;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.Client;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.DependencyInjection;
public class FixedMvcCachedApplicationConfigurationClient : MvcCachedApplicationConfigurationClient, ITransientDependency
{
private readonly IAbpApplicationLocalizationAppService _localizationAppService;
public FixedMvcCachedApplicationConfigurationClient(
IAbpApplicationConfigurationAppService applicationConfigurationAppService,
IAbpApplicationLocalizationAppService localizationAppService)
: base(applicationConfigurationAppService, localizationAppService)
{
_localizationAppService = localizationAppService;
}
protected override Task<ApplicationLocalizationDto> GetLocalizationAsync()
{
// Ensure cultureName is never missing
var cultureName = CultureInfo.CurrentUICulture?.Name;
if (string.IsNullOrWhiteSpace(cultureName))
{
cultureName = "en";
}
return _localizationAppService.GetAsync(new ApplicationLocalizationRequestDto
{
CultureName = cultureName,
OnlyDynamics = true
});
}
}
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.AspNetCore.Mvc.Client;
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Replace(ServiceDescriptor.Transient<
MvcCachedApplicationConfigurationClient,
FixedMvcCachedApplicationConfigurationClient>());
}
This guarantees the call becomes:
/api/abp/application-localization?cultureName=en...
and avoids the startup crash even if something in your environment is preventing ABP from determining culture normally.
Your logs prove the request is being made without cultureName. The ABP endpoint requires it, and returns 400 when it’s missing. By forcing the client to always send a non-empty culture, you bypass the failing path and your UI can start.
/api/abp/application-localization requires cultureName: https://abp.io/docs/10.2/framework/api-development/standard-apis/localizationThis response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.