Open Closed

After we migrated ABP 7.3.1 to 8.1.1, I got "Tenant not found" error #7190


User avatar
0
uyarbtrlp created
  • ABP Framework version: v8.1.1
  • UI Type: MVC
  • Database System: EF Core
  • Module project (Separated Deployment & Databases Scenario): yes

Hello, After we upgraded ABP v8.1.1, we got "Tenant not found! There is no tenant with the tenant id or name: a3e378cf-c315-7b7e-da30-3a12881a6c2a" exception while trying to login the application via Web.Host project. We've been using the application without redis so we've disabled it.

  "Redis": {
    "IsEnabled": "false",
    "Configuration": "127.0.0.1"
  },

When we enable the redis, there is no problem. We are able to login. So I've decided creating a new module project on abp suite to test the same thing.

  1. Create a module project on abp suite
  2. Update the databases to create the tables
  3. Disable the redis on appsettings.json
  4. I've changed the TestApplicationNet8SampleIdentityDataSeeder on AuthServer project to seed the users when the tenant is created
  5. Create a tenant
  6. Login with this tenant and get the exception

7 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Create a module project on abp suite

    Can you share this project via https://wetransfer.com/

    liming.ma@volosoft.com

    Thanks

  • User Avatar
    0
    uyarbtrlp created

    I've sent it

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Login with this tenant and get the exception

    What projects of host are you running?

  • User Avatar
    0
    uyarbtrlp created

    I am running AuthServer, HttpApi.Host and Web.Host

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I confirmed. You have to use Redis in tiered projects. otherwise, you may get some strange problems.

    but you can try the code below:

    host/TestApplicationNet8.Web.Host/MyMvcRemoteTenantStore.cs

    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Options;
    using Pages.Abp.MultiTenancy.ClientProxies;
    using Volo.Abp.AspNetCore.Mvc.Client;
    using Volo.Abp.Caching;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.MultiTenancy;
    using Volo.Abp.Threading;
    
    namespace TestApplicationNet8;
    
    [ExposeServices(typeof(ITenantStore))]
    public class MyMvcRemoteTenantStore :  ITenantStore, ITransientDependency
    {
        protected AbpTenantClientProxy TenantAppService { get; }
        protected IHttpContextAccessor HttpContextAccessor { get; }
        protected IDistributedCache<TenantConfigurationCacheItem> Cache { get; }
        protected AbpAspNetCoreMvcClientCacheOptions Options { get; }
    
        public MyMvcRemoteTenantStore(
            AbpTenantClientProxy tenantAppService,
            IHttpContextAccessor httpContextAccessor,
            IDistributedCache<TenantConfigurationCacheItem> cache,
            IOptions<AbpAspNetCoreMvcClientCacheOptions> options)
        {
            TenantAppService = tenantAppService;
            HttpContextAccessor = httpContextAccessor;
            Cache = cache;
            Options = options.Value;
        }
    
        public async Task<TenantConfiguration?> FindAsync(string normalizedName)
        {
            var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName);
            var httpContext = HttpContextAccessor?.HttpContext;
    
            if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext)
            {
                return tenantConfigurationInHttpContext?.Value;
            }
    
            var tenantConfiguration = await Cache.GetAsync(cacheKey);
            if (tenantConfiguration?.Value == null)
            {
                var tenant = await TenantAppService.FindTenantByNameAsync(normalizedName);
                if (tenant.Success)
                {
                    tenantConfiguration = new TenantConfigurationCacheItem(new TenantConfiguration(tenant.TenantId!.Value, tenant.NormalizedName!));
                    await Cache.SetAsync(cacheKey, tenantConfiguration);
                }
            }
    
            if (httpContext != null)
            {
                httpContext.Items[cacheKey] = tenantConfiguration;
            }
    
            return tenantConfiguration?.Value;
        }
    
        public async Task<TenantConfiguration?> FindAsync(Guid id)
        {
            var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(id);
            var httpContext = HttpContextAccessor?.HttpContext;
    
            if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext)
            {
                return tenantConfigurationInHttpContext?.Value;
            }
    
            var tenantConfiguration = await Cache.GetAsync(cacheKey);
            if (tenantConfiguration?.Value == null)
            {
                var tenant = await TenantAppService.FindTenantByIdAsync(id);
                if (tenant.Success)
                {
                    tenantConfiguration = new TenantConfigurationCacheItem(new TenantConfiguration(tenant.TenantId!.Value, tenant.NormalizedName!));
                    await Cache.SetAsync(cacheKey, tenantConfiguration);
                }
            }
    
            if (httpContext != null)
            {
                httpContext.Items[cacheKey] = tenantConfiguration;
            }
    
            return tenantConfiguration?.Value;
        }
    
        public Task<IReadOnlyList<TenantConfiguration>> GetListAsync(bool includeDetails = false)
        {
            return Task.FromResult<IReadOnlyList<TenantConfiguration>>(Array.Empty<TenantConfiguration>());
        }
    
        public TenantConfiguration? Find(string normalizedName)
        {
            var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName);
            var httpContext = HttpContextAccessor?.HttpContext;
    
            if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext)
            {
                return tenantConfigurationInHttpContext?.Value;
            }
    
            var tenantConfiguration = Cache.Get(cacheKey);
            if (tenantConfiguration?.Value == null)
            {
                var tenant = AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByNameAsync(normalizedName));
                if (tenant.Success)
                {
                    tenantConfiguration = new TenantConfigurationCacheItem(new TenantConfiguration(tenant.TenantId!.Value, tenant.NormalizedName!));
                    Cache.Set(cacheKey, tenantConfiguration);
                }
            }
    
            if (httpContext != null)
            {
                httpContext.Items[cacheKey] = tenantConfiguration;
            }
    
            return tenantConfiguration?.Value;
        }
    
        public TenantConfiguration? Find(Guid id)
        {
            var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(id);
            var httpContext = HttpContextAccessor?.HttpContext;
    
            if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext)
            {
                return tenantConfigurationInHttpContext?.Value;
            }
    
            var tenantConfiguration = Cache.Get(cacheKey);
            if (tenantConfiguration?.Value == null)
            {
                var tenant = AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByIdAsync(id));
                if (tenant.Success)
                {
                    tenantConfiguration = new TenantConfigurationCacheItem(new TenantConfiguration(tenant.TenantId!.Value, tenant.NormalizedName!));
                    Cache.Set(cacheKey, tenantConfiguration);
                }
            }
    
            if (httpContext != null)
            {
                httpContext.Items[cacheKey] = tenantConfiguration;
            }
    
            return tenantConfiguration?.Value;
        }
    }
    
    
  • User Avatar
    0
    uyarbtrlp created

    It appears that it is a problem with the newest version. We haven't experienced such an issue so far. Btw, I've tried the code above and it works. If I understand correctly, we MUST enable the redis with tiered applications after v8.0, right?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Yes, You have to enable the Redis.

    https://support.abp.io/QA/Questions/6533/Why-do-I-need-the-Redis-cache-for-the-public-website#answer-3a10363f-48d7-73fe-88fc-51114ebe105d

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19