Activities of "maliming"

hi

You need to replace the built-in Login page and add your step2 choose tenant page.

The system will redirect to a page in authServer where the system will display a list of tenants that the user has been assigned to. user can choose from the tenants assigned to them.!

The redirect code exists on OnGetExternalLoginCallbackAsync method of Volo.Abp.Account.Pro.Public.Web/Pages/Account/Login.cshtml.cs.

so you redirect the user to your custom page on the OnGetExternalLoginCallbackAsync method. then show the tenant list and set the new tenant for a new user.

You better download the source code of account pro to check the code.

hi

Can you try again, your email was not confirmed.

Answer

hi

There are two integration services in the microservices project.

IPermissionIntegrationService and IIdentityUserIntegrationService

It is easy to add a new integration service to your module. https://docs.abp.io/en/abp/latest/Integration-Services

You can give it a try. Feel free to give feedback if you have any problems.

Thanks.

Answer

hi

The tenant(TenantId) is set when a user is created.

https://github.com/abpframework/abp/blob/dev/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs#L165

  1. There may be some related user data, so you can delete a user and re-create a new user with a specific tenant
  2. You can change the TenantId of a user by ObjectHelper
var user = await UserManager.GetByIdAsync
ObjectHelper.TrySetProperty(user, x => x.TenantId, () => NewTenantId);

hi

I will check if I can reproduce it in a new 8.0 project.

Thanks.

The PR of ABP framework.

https://github.com/abpframework/abp/pull/19523

hi

I updated the code. Can you test the latest one?

I will try to find a better way.

hi

Try to override the protected override void PublishEventsForTrackedEntity(EntityEntry entry) method.

The key changes are:

if (entry.Properties.Where(x => x.IsModified).All(x => x.Metadata.IsForeignKey()))
{
    // Skip if only foreign keys are changed.
    break;
}
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
using Volo.Abp.BlobStoring.Database.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.LanguageManagement.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TextTemplateManagement.EntityFrameworkCore;
using Volo.Saas.EntityFrameworkCore;
using Volo.Saas.Editions;
using Volo.Saas.Tenants;
using Volo.Abp.Gdpr;
using Volo.Abp.OpenIddict.EntityFrameworkCore;
using BugTracker.Examples;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;

namespace BugTracker.EntityFrameworkCore;

[ReplaceDbContext(typeof(IIdentityProDbContext))]
[ReplaceDbContext(typeof(ISaasDbContext))]
[ConnectionStringName("Default")]
public class BugTrackerDbContext :
    AbpDbContext<BugTrackerDbContext>,
    IIdentityProDbContext,
    ISaasDbContext
{
    /* Add DbSet properties for your Aggregate Roots / Entities here. */

    public DbSet<ParentEntity> ParentEntities { get; set; }

    #region Entities from the modules

    /* Notice: We only implemented IIdentityProDbContext and ISaasDbContext
     * and replaced them for this DbContext. This allows you to perform JOIN
     * queries for the entities of these modules over the repositories easily. You
     * typically don't need that for other modules. But, if you need, you can
     * implement the DbContext interface of the needed module and use ReplaceDbContext
     * attribute just like IIdentityProDbContext and ISaasDbContext.
     *
     * More info: Replacing a DbContext of a module ensures that the related module
     * uses this DbContext on runtime. Otherwise, it will use its own DbContext class.
     */

    // Identity
    public DbSet<IdentityUser> Users { get; set; }
    public DbSet<IdentityRole> Roles { get; set; }
    public DbSet<IdentityClaimType> ClaimTypes { get; set; }
    public DbSet<OrganizationUnit> OrganizationUnits { get; set; }
    public DbSet<IdentitySecurityLog> SecurityLogs { get; set; }
    public DbSet<IdentityLinkUser> LinkUsers { get; set; }
    public DbSet<IdentityUserDelegation> UserDelegations { get; set; }
    public DbSet<IdentitySession> Sessions { get; set; }

    // SaaS
    public DbSet<Tenant> Tenants { get; set; }
    public DbSet<Edition> Editions { get; set; }
    public DbSet<TenantConnectionString> TenantConnectionStrings { get; set; }

    #endregion

    public BugTrackerDbContext(DbContextOptions<BugTrackerDbContext> options)
        : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        /* Include modules to your migration db context */

        builder.ConfigurePermissionManagement();
        builder.ConfigureSettingManagement();
        builder.ConfigureBackgroundJobs();
        builder.ConfigureAuditLogging();
        builder.ConfigureIdentityPro();
        builder.ConfigureOpenIddictPro();
        builder.ConfigureFeatureManagement();
        builder.ConfigureLanguageManagement();
        builder.ConfigureSaas();
        builder.ConfigureTextTemplateManagement();
        builder.ConfigureBlobStoring();
        builder.ConfigureGdpr();

        /* Configure your own tables/entities inside here */

        //builder.Entity<YourEntity>(b =>
        //{
        //    b.ToTable(BugTrackerConsts.DbTablePrefix + "YourEntities", BugTrackerConsts.DbSchema);
        //    b.ConfigureByConvention(); //auto configure for the base class props
        //    //...
        //});

        builder.Entity<ParentEntity>(b =>
        {
            b.ToTable(BugTrackerConsts.DbTablePrefix + "ParentEntities",
                BugTrackerConsts.DbSchema);
            b.ConfigureByConvention(); //auto configure for the base class props

            b.HasMany(x => x.SubEntities).WithOne();
        });

        builder.Entity<SubEntity>(b =>
        {
            b.ToTable(BugTrackerConsts.DbTablePrefix + "SubEntities",
                BugTrackerConsts.DbSchema);
            b.ConfigureByConvention(); //auto configure for the base class props
        });
    }
    
    protected override void PublishEventsForTrackedEntity(EntityEntry entry)
    {
        switch (entry.State)
        {
            case EntityState.Added:
                ApplyAbpConceptsForAddedEntity(entry);
                EntityChangeEventHelper.PublishEntityCreatedEvent(entry.Entity);
                break;

            case EntityState.Modified:
                ApplyAbpConceptsForModifiedEntity(entry);
                if (entry.Properties.Any(x => x.IsModified && (x.Metadata.ValueGenerated == ValueGenerated.Never || x.Metadata.ValueGenerated == ValueGenerated.OnAdd)))
                {
                    if (entry.Properties.Where(x => x.IsModified).All(x => x.Metadata.IsForeignKey()))
                    {
                        // Skip if only foreign keys are changed.
                        break;
                    }
                    if (entry.Entity is ISoftDelete && entry.Entity.As<ISoftDelete>().IsDeleted)
                    {
                        EntityChangeEventHelper.PublishEntityDeletedEvent(entry.Entity);
                    }
                    else
                    {
                        EntityChangeEventHelper.PublishEntityUpdatedEvent(entry.Entity);
                    }
                }
                break;

            case EntityState.Deleted:
                ApplyAbpConceptsForDeletedEntity(entry);
                EntityChangeEventHelper.PublishEntityDeletedEvent(entry.Entity);
                break;
        }

        if (EntityChangeOptions.Value.PublishEntityUpdatedEventWhenNavigationChanges)
        {
            foreach (var entityEntry in ChangeTracker.Entries().Where(x => x.State == EntityState.Unchanged && AbpEfCoreNavigationHelper.IsEntityEntryNavigationChanged(x)))
            {
                if (entityEntry.Entity is ISoftDelete && entityEntry.Entity.As<ISoftDelete>().IsDeleted)
                {
                    EntityChangeEventHelper.PublishEntityDeletedEvent(entityEntry.Entity);
                }
                else
                {
                    EntityChangeEventHelper.PublishEntityUpdatedEvent(entityEntry.Entity);
                }
            }
        }
    }
}

hi

Please make this repo private I have downloaded the sourecode.

Thanks.

Showing 5151 to 5160 of 11567 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.