Activities of "maliming"

I can provide a sample proj that I genererated recently.

Please share a simple sample. Thanks

liming.ma@volosoft.com

hi

Can you use the code below to test your connection string and see the exception details?

https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/ConnectionStrings/SqlServerConnectionStringChecker.cs#L23-L38

hi

invalid Connection String

It works on my machine. What is the exception when you test connection string?

https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/ConnectionStrings/SqlServerConnectionStringChecker.cs#L35

Login to this tenant option is missing

Try to add to your oAuthConfig

impersonation: {
    userImpersonation: true,
    tenantImpersonation: true,
  },

hi

This module is calling a third party API which required an URL, username and password.

Which layer is this class in the module? application? domain?

You can add a MyOptions class in the same layer. and inject the IOptions<MyOptions> in your service to get value. Then, configure this option from appsettings.json or somewhere else in the microservice project.

The OpenIddictApplication did not change when I requested a token.

hi

Add this MyMultiTenantConnectionStringResolver class to your project. We will fix this problem. Sorry for that.

using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;

namespace AbpMultiTenant.AuthServer;

[Dependency(ReplaceServices = true)]
public class MyMultiTenantConnectionStringResolver : DefaultConnectionStringResolver
{
    private readonly ICurrentTenant _currentTenant;
    private readonly IServiceProvider _serviceProvider;

    public MyMultiTenantConnectionStringResolver(
        IOptionsMonitor<AbpDbConnectionOptions> options,
        ICurrentTenant currentTenant,
        IServiceProvider serviceProvider)
        : base(options)
    {
        _currentTenant = currentTenant;
        _serviceProvider = serviceProvider;
    }

    public override async Task<string> ResolveAsync(string? connectionStringName = null)
    {
        if (_currentTenant.Id == null)
        {
            //No current tenant, fallback to default logic
            return await base.ResolveAsync(connectionStringName);
        }

        var tenant = await FindTenantConfigurationAsync(_currentTenant.Id.Value);

        if (tenant == null || tenant.ConnectionStrings.IsNullOrEmpty())
        {
            //Tenant has not defined any connection string, fallback to default logic
            return await base.ResolveAsync(connectionStringName);
        }

        var tenantDefaultConnectionString = tenant.ConnectionStrings?.Default;

        //Requesting default connection string...
        if (connectionStringName == null ||
            connectionStringName == ConnectionStrings.DefaultConnectionStringName)
        {
            //Return tenant's default or global default
            return !tenantDefaultConnectionString.IsNullOrWhiteSpace()
                ? tenantDefaultConnectionString!
                : Options.ConnectionStrings.Default!;
        }

        //Requesting specific connection string...
        var connString = tenant.ConnectionStrings?.GetOrDefault(connectionStringName);
        if (!connString.IsNullOrWhiteSpace())
        {
            //Found for the tenant
            return connString!;
        }

        //Fallback to the mapped database for the specific connection string
        var database = Options.Databases.GetMappedDatabaseOrNull(connectionStringName);
        if (database != null && database.IsUsedByTenants)
        {
            connString = tenant.ConnectionStrings?.GetOrDefault(database.DatabaseName);
            if (!connString.IsNullOrWhiteSpace())
            {
                //Found for the tenant
                return connString!;
            }
        }

        //Fallback to tenant's default connection string if available
        if (!tenantDefaultConnectionString.IsNullOrWhiteSpace())
        {
            return tenantDefaultConnectionString!;
        }

        return await base.ResolveAsync(connectionStringName);
    }

    [Obsolete("Use ResolveAsync method.")]
    public override string Resolve(string? connectionStringName = null)
    {
        if (_currentTenant.Id == null)
        {
            //No current tenant, fallback to default logic
            return base.Resolve(connectionStringName);
        }

        var tenant = FindTenantConfiguration(_currentTenant.Id.Value);

        if (tenant == null || tenant.ConnectionStrings.IsNullOrEmpty())
        {
            //Tenant has not defined any connection string, fallback to default logic
            return base.Resolve(connectionStringName);
        }

        var tenantDefaultConnectionString = tenant.ConnectionStrings?.Default;

        //Requesting default connection string...
        if (connectionStringName == null ||
            connectionStringName == ConnectionStrings.DefaultConnectionStringName)
        {
            //Return tenant's default or global default
            return !tenantDefaultConnectionString.IsNullOrWhiteSpace()
                ? tenantDefaultConnectionString!
                : Options.ConnectionStrings.Default!;
        }

        //Requesting specific connection string...
        var connString = tenant.ConnectionStrings?.GetOrDefault(connectionStringName);
        if (!connString.IsNullOrWhiteSpace())
        {
            //Found for the tenant
            return connString!;
        }

        //Fallback to the mapped database for the specific connection string
        var database = Options.Databases.GetMappedDatabaseOrNull(connectionStringName);
        if (database != null && database.IsUsedByTenants)
        {
            connString = tenant.ConnectionStrings?.GetOrDefault(database.DatabaseName);
            if (!connString.IsNullOrWhiteSpace())
            {
                //Found for the tenant
                return connString!;
            }
        }

        //Fallback to tenant's default connection string if available
        if (!tenantDefaultConnectionString.IsNullOrWhiteSpace())
        {
            return tenantDefaultConnectionString!;
        }

        return base.Resolve(connectionStringName);
    }

    protected virtual async Task<TenantConfiguration?> FindTenantConfigurationAsync(Guid tenantId)
    {
        using (var serviceScope = _serviceProvider.CreateScope())
        {
            var tenantStore = serviceScope
                .ServiceProvider
                .GetRequiredService<ITenantStore>();

            return await tenantStore.FindAsync(tenantId);
        }
    }

    [Obsolete("Use FindTenantConfigurationAsync method.")]
    protected virtual TenantConfiguration? FindTenantConfiguration(Guid tenantId)
    {
        using (var serviceScope = _serviceProvider.CreateScope())
        {
            var tenantStore = serviceScope
                .ServiceProvider
                .GetRequiredService<ITenantStore>();

            return tenantStore.Find(tenantId);
        }
    }
}

you will see the record in the OpenIddictApplication table gets updated on each call to connect/token endpoint with client_credentials granttype.

OK I will try that. Can you share the HTTP request logs of your connect/token endpoint with client_credentials granttype.

hi

ok, I will check it asap.

https://github.com/PCAssistSoftware/ABPTest/pull/1

hi

Can you share your project via https://wetransfer.com/?

liming.ma@volosoft.com

Showing 3641 to 3650 of 11565 entries
Learn More, Pay Less
33% OFF
All Trainings!
Get Your Deal
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on December 25, 2025, 06:16
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.