0
oguzhanacikgoez created
Hi,
at first i have to say "Great Work!" to Halil. You have built the most genius architecture I have seen before, thank you for that. In my application I created multiple tenants for my customers. Currently they're log-in with the default form and need to put the tenant name in the input field. For a better user experience I target to detect the tenant by requested URL. customer1.myapp.com -> runs the application with the customer1 database
How could i solve this issue, any idea?
1 Answer(s)
-
0
Hi,
First of all thanks :).
You need to create a new session of yours like this.
public class AspNetZeroAbpSession : ClaimsAbpSession { public ITenantIdAccessor TenantIdAccessor { get; set; } public override int? TenantId { get { if (base.TenantId != null) { return base.TenantId; } //Try to find tenant from ITenantIdAccessor, if provided return TenantIdAccessor?.GetCurrentTenantIdOrNull(false); //set false to prevent circular usage. } } public AspNetZeroAbpSession(IMultiTenancyConfig multiTenancy) : base(multiTenancy) { } }
public class TenantIdAccessor : ITenantIdAccessor, ISingletonDependency { private const string HttpContextKey = "AbpZeroCurrentTenantCacheItem"; private readonly ITenantCache _tenantCache; private readonly IIocResolver _iocResolver; private readonly AsyncLocal<int?> _currentTenant; private readonly Lazy<IAbpSession> _abpSession; private readonly Lazy<ITenancyNameFinder> _tenancyNameFinder; private int? CurrentTenantId { get { if (HttpContext.Current != null) { _currentTenant.Value = HttpContext.Current.Items[HttpContextKey] as int?; return _currentTenant.Value; } return _currentTenant.Value; } set { _currentTenant.Value = value; if (HttpContext.Current != null) { HttpContext.Current.Items[HttpContextKey] = _currentTenant.Value; } } } public TenantIdAccessor( ITenantCache tenantCache, IIocResolver iocResolver) { _tenantCache = tenantCache; _iocResolver = iocResolver; _currentTenant = new AsyncLocal<int?>(); _abpSession = new Lazy<IAbpSession>(() => _iocResolver.Resolve<IAbpSession>(), true); _tenancyNameFinder = new Lazy<ITenancyNameFinder>(() => _iocResolver.Resolve<ITenancyNameFinder>(), true); } /// <summary> /// Gets current tenant id. /// Use <see cref="IAbpSession.TenantId"/> wherever possible (if user logged in). /// This method tries to get current tenant id even if current user did not log in. /// </summary> /// <param name="useSession">Set false to skip session usage</param> public int? GetCurrentTenantIdOrNull(bool useSession = true) { if (useSession) { return _abpSession.Value.TenantId; } return CurrentTenantId; } /// <summary> /// This method is called on request beginning to obtain current tenant id. /// </summary> public void SetCurrentTenantId() { var tenancyName = _tenancyNameFinder.Value.GetCurrentTenancyNameOrNull(); if (tenancyName == null) { CurrentTenantId = null; return; } CurrentTenantId = _tenantCache.GetOrNull(tenancyName)?.Id; } }
Then replace IAbpSession with your session on your core module's PreInitialize method.
Configuration.ReplaceService<IAbpSession, AspNetZeroAbpSession>();
Finally, use below code in your Global.asax's Application_AuthenticateRequest.
if (User?.Identity != null && User.Identity.IsAuthenticated) { return; } using (var currentTenantAccessor = AbpBootstrapper.IocManager.ResolveAsDisposable<TenantIdAccessor>()) { currentTenantAccessor.Object.SetCurrentTenantId(); }