Activities of "maliming"

Hi,

The old NuGet key has been revoked. Requests with it now get a 401 from nuget.abp.io.

You don't need to change your AbpLicenseCode. It is not related to the NuGet key. Only update the NuGet source URL in your NuGet.Config files and in your CI configuration.

Your previous reply here still shows the old key. Please edit it and remove the key.

Thanks

Hi,

Your idp-api router uses PathPrefix(`/account`), but Traefik path matching is case-sensitive, so /Account/Login doesn't match it and goes to the React app. Changing it to /Account is not enough either, because the login page also loads files from /libs, /__bundles and /Abp on the backend.

It's easier to do it the other way around: send everything to the backend by default, and only send the React files and pages to the React app. Please change these labels in your compose file (use your domain) and keep the other labels as they are:

  idp-api:
    labels:
      - "traefik.http.routers.idp-api.rule=Host(`idp.example.com`)"
      - "traefik.http.routers.idp-api.priority=10"

  idp-web:
    labels:
      - "traefik.http.routers.idp-web.rule=Host(`idp.example.com`) && (Path(`/`) || Path(`/index.html`) || Path(`/dynamic-env.json`) || Path(`/getEnvConfig`) || Path(`/silent-renew.html`) || Path(`/favicon.png`) || PathPrefix(`/assets/`) || PathRegexp(`^/(identity|403|dynamic)(/|$)`) || Path(`/account`) || Path(`/account/`) || PathRegexp(`^/account/(login|register|forgot-password|reset-password)$`))"
      - "traefik.http.routers.idp-web.priority=100"

dynamic is for the LowCode pages. If you add your own React pages, add their root paths to the PathRegexp list.

Thanks

Hi,

I only got the email with the logs and screenshots. They show that /Account/Login returns the React page instead of the ABP login page, so the routing for this domain needs to be fixed.

Could you share:

  1. Your Traefik version and the Traefik config for idp.example.com (Docker labels or dynamic config files, with the routers, rules, priorities and services). Please remove any secrets.
  2. Do you also deploy the public website? If so, on which domain or path?

Thanks

Hi,

ABP 10.4.1 has a bug here. When a token is created or updated, ABP also updates the ConcurrencyStamp of the related OpenIddictAuthorization if it's loaded in the same DbContext. So concurrent token requests under the same authorization can conflict and throw AbpDbConcurrencyException.

It's fixed in 10.6.0: https://github.com/abpframework/abp/pull/25824

For 10.4.1, you can add the same change to ConfigureServices of the module of your app that handles /connect/token:

using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.OpenIddict.Authorizations;

Configure<AbpEntityChangeOptions>(options =>
{
    options.IgnoredNavigationEntitySelectors.Add("DisableOpenIddictAuthorization", type => type == typeof(OpenIddictAuthorization));
});

You can remove it after upgrading to 10.6.0 or later.

AbpOpenIddictTokenStore.UpdateAsync already converts the exception to OpenIddictExceptions.ConcurrencyException, but it logs the original error first. So if two requests really update the same token at the same time, you'll still see this error in the logs. That's expected.

If you still get unhandled exceptions after this change, please share the full exception and the request path of one of them.

Thanks

Hi,

The test projects option is only in the new solution and new module wizards. For an existing solution, you can generate the same solution again with tests in a temp folder, then copy the test project into your solution.

  1. Open your .abpsln file. Under creatingStudioConfiguration, you'll find createdAbpStudioVersion and createCommand.

  2. Install that CLI version into a separate folder, so you get the same template your solution was created from. Then run the createCommand with it in an empty folder, and add --tests --skip-initial-tasks at the end:

dotnet tool install Volo.Abp.Studio.Cli --version <createdAbpStudioVersion> --tool-path C:\Temp\abp-cli
mkdir C:\Temp\with-tests
cd C:\Temp\with-tests
C:\Temp\abp-cli\abp new YourCompany.YourProject -t app-nolayers --modern --modular ... --tests --skip-initial-tasks
  1. Copy the generated YourCompany.YourProject.Tests folder into your solution folder, next to the main project. Then go back to your solution folder, add it to the solution and run the tests:
cd <your solution folder>
dotnet sln YourCompany.YourProject.slnx add YourCompany.YourProject.Tests/YourCompany.YourProject.Tests.csproj
dotnet test YourCompany.YourProject.Tests/YourCompany.YourProject.Tests.csproj

If you've upgraded ABP or .NET since you created the solution, update the package versions and TargetFramework in the test .csproj first.

If you have the Books sample page, Should_Create_A_Valid_Book may fail with a FOREIGN KEY constraint failed error. The test doesn't set AuthorId. Add these usings to the BookAppService_Tests file:

using YourCompany.YourProject.Entities.Authors;
using Volo.Abp.Domain.Repositories;

And change the create part of the test like this:

var author = await WithUnitOfWorkAsync(() => GetRequiredService<IRepository<Author, Guid>>().FirstAsync());

var result = await _bookAppService.CreateAsync(
    new CreateUpdateBookDto
    {
        Name = "New test book 42",
        AuthorId = author.Id,
        Price = 10,
        PublishDate = DateTime.Now,
        Type = BookType.ScienceFiction
    }
);

Modules work the same way. With the same CLI, create a module with the same name, template and database provider in the temp solution:

C:\Temp\abp-cli\abp new-module YourCompany.YourProject.ModuleName -t module:standard-modern -d ef -ts C:\Temp\with-tests\YourCompany.YourProject.abpsln -o C:\Temp\with-tests\modules\modulename

Use -t module:ddd-modern for a DDD module, and -d mongodb if the module uses MongoDB. Then copy the test projects to the same place in your module (for a standard module it's the *.Tests folder, for a DDD module it's the whole test folder). Also copy the test entries from the temp module's .slnx and .abpmdl files into yours, and run dotnet test on the module's .slnx.

Thanks

Hi,

Please send an email to license@abp.io from your organization owner's email address and include the link to this question. We will reset the NuGet API key for your organization.

After that, you can find the new key on the "My organizations" page on abp.io. Then update the NuGet source URL in your NuGet.Config files and in your CI configuration.

Thanks

Hi,

Your reverse proxy sends /Account/Login to the React app, not to the ABP app. The React app has its own /account/login page, which starts the login again, so it keeps going /connect/authorize -> /Account/Login -> React -> /connect/authorize.

The fix depends on how you want to host the apps. Could you share:

  1. Do you want to keep the React app and the ABP app on the same domain, or can the React app use its own domain, for example app.example.com?
  2. Your Traefik config for this domain (routers, rules, priorities and services). Please remove any secrets.
  3. Do you also deploy the public website? If so, on which domain or path?

Thanks

Hi,

This is caused by the runtime database migrator. When a deploy includes a new migration, it publishes an event directly to Azure Service Bus and waits for it before the host starts. After the restart there is no new migration, so the service starts fast.

You can override LockAndApplyDatabaseMigrationsAsync in your XxxRuntimeDatabaseMigrator so the event goes to the outbox instead. Replace YourDbContext with the DbContext of that migrator:

using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
private bool _isAppliedDatabaseMigrationsEventPending;

protected override async Task LockAndApplyDatabaseMigrationsAsync()
{
    Logger.LogInformation($"Trying to acquire the distributed lock for database migration: {DatabaseName}.");

    var schemaMigrated = false;

    await using (var handle = await DistributedLock.TryAcquireAsync("DatabaseMigration_" + DatabaseName))
    {
        if (handle is null)
        {
            if (_isAppliedDatabaseMigrationsEventPending)
            {
                throw new AbpException($"Distributed lock could not be acquired to save the {nameof(AppliedDatabaseMigrationsEto)} for database migration: {DatabaseName}.");
            }

            Logger.LogInformation($"Distributed lock could not be acquired for database migration: {DatabaseName}. Operation cancelled.");
            return;
        }

        Logger.LogInformation($"Distributed lock is acquired for database migration: {DatabaseName}...");

        using (CurrentTenant.Change(null))
        {
            using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
            {
                var dbContext = await ServiceProvider
                    .GetRequiredService<IDbContextProvider<YourDbContext>>()
                    .GetDbContextAsync();

                var pendingMigrations = await dbContext.Database.GetPendingMigrationsAsync();
                if (pendingMigrations.Any())
                {
                    await dbContext.Database.MigrateAsync();
                    schemaMigrated = true;
                }

                await uow.CompleteAsync();
            }
        }

        await SeedAsync();

        if (schemaMigrated || AlwaysSeedTenantDatabases || _isAppliedDatabaseMigrationsEventPending)
        {
            // If saving fails, the retry has no pending migrations, so this flag makes it save the event again.
            _isAppliedDatabaseMigrationsEventPending = true;

            using (CurrentTenant.Change(null))
            {
                using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
                {
                    await DistributedEventBus.PublishAsync(new AppliedDatabaseMigrationsEto
                    {
                        DatabaseName = DatabaseName,
                        TenantId = null
                    });

                    await uow.CompleteAsync();
                }
            }

            _isAppliedDatabaseMigrationsEventPending = false;
        }
    }

    Logger.LogInformation($"Distributed lock has been released for database migration: {DatabaseName}...");
}

This needs the outbox configured for that DbContext. The microservice template does it by default.

We'll fix this in the framework too.

Thanks

Hi,

Could you share the following so we can see where the loop happens:

  1. The app logs from the time the loop happens, with debug level enabled. See https://abp.io/support/questions/8622/How-to-enable-Debug-logs-for-troubleshoot-problems
  2. The first few redirects from the browser Network tab, with the Location header of each one.
  3. Does the loop start as soon as you open the page, or after you enter the username and password?

You can also send them to liming.ma@volosoft.com if you don't want to share them here.

Thanks

Hi,

ForwardedHeadersOptions only trusts loopback proxies by default. Your reverse proxy connects from a Docker network IP, so the X-Forwarded-Proto header is ignored and OpenIddict still sees an HTTP request.

Please clear the known proxy lists:

Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownIPNetworks.Clear();
    options.KnownProxies.Clear();
});

Also make sure the proxy sends X-Forwarded-Proto: https. If the app can be reached without going through the proxy, add the proxy IP to KnownProxies instead of clearing the lists.

Thanks

Showing 41 to 50 of 12910 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on October 30, 2026, 06:34
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.