Thanks for the response. I solved this problem, but there was a problem with the login process. Although authentication is successful in the login process, redirect_uri is looping in a meaningless way and requests are constantly thrown on the screen. In Firefox I get an unauthorized site screen, in Chrome the request ends with stopped because the url is too long. If I press F5 and refresh the screen, the site comes up correctly.
Unfortunately I couldn't overcome this problem so I reverted back to version 7.4.
I updated my commercial project from 7.4 to 9.1. The multi-tenant system is active. When I try to enter the administration (Angular) panel on the server, it automatically brings “api” to the end of the subdomain name and a subdomain address that I do not have appears and falls into CORS error.
For host tenant: Angular subdomain : xtest Api subdomain : xapitest
Faulty subdomain that the system automatically tries to go to: xtestapi
Is there anywhere I need to change about this after the update?
I guess I didn't express my request clearly and I apologize for that. I have knowledge about concurrency. If I didn't use abp.io, I would know how to avoid this conflict. I wanted to know how abp.io would behave when multiple hangfire workers are running at the same time, if the dbcontext in the hangfire workers has unitofwork instances created there. I would even like to know how you proceeded if you have dealt with such a development before.
I guess I will test this and find out.
Thank you liangshiwei for your attention and help.
I want to learn that if I run one more background worker of hangfire in ABP.IO and create new Scope instance there. If I create my UnitOfWorkManager and DomainService instances from that scope, can I avoid dbcontext concurrency conflict?
First of all, thank you for your answers.
To avoid this type of conflict in .NET forms, it is recommended to create different instances of dbcontext. It is said that there may be a concurrency problem with the same dbcontext.
If you have an abp.io project and you are using hangfire background workers that use dbcontext (maybe with different tables), what kind of coding would you do ? Is there an example ? How can I provide this safely in the hangfire module in ABP.IO ?
As far as I understand, a redis db is added for lock tracking and the locking handle of the methods of the requested services is used.
I have a postgresql database and I have a project. Inside there are different workers using the same dbcontext. If you interpret the code in the picture, would it be safer to have the unitofwork block outside the scope block or inside the scope block to avoid concurrency issues or injecting a new instance of dbcontext into the manager classes?
Hello there
We know that there is a problem with the dbcontext class running concurrently in the same scope.
In Hangfire, if different background workers run at the same time, will there be a concurrency problem when recording data related to dbcontext? How is it safe to use multiple dbcontexts in ABP.IO in Hangfire at the same time?
I am attaching below the working code in a sample worker (DoWorkAsync method in HangfireBackgroundWorkerBase class). Is it ok if all my worker classes work like this?
Sorry, my bad. You're right.
In the LeptonX, it'll be
Themes/LeptonX/Layouts/Account/Default.cshtml
You can override this file for Account layout of LeptonX and existing content is below:@using Microsoft.Extensions.Localization @using Microsoft.Extensions.Options @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX @using Volo.Abp.LeptonX.Shared.Localization; @using Volo.Abp.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling @using Volo.Abp.AspNetCore.Mvc.UI.Theming @using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts @using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles @using Volo.Abp.Ui.Branding @using Volo.Abp.AspNetCore.Mvc.AntiForgery @using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization @using Volo.Abp.AspNetCore.MultiTenancy @using Volo.Abp.MultiTenancy @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Themes.LeptonX.Components.Common.PageAlerts @using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Themes.LeptonX.Components.SideMenu.Toolbar.LanguageSwitch @using Microsoft.AspNetCore.Http.Extensions @using Volo.Abp.Ui.LayoutHooks @inject IAbpAntiForgeryManager AbpAntiForgeryManager @inject IBrandingProvider BrandingProvider @inject LeptonXStyleProvider LeptonXStyleProvider @inject IStringLocalizer<AbpUiMultiTenancyResource> MultiTenancyStringLocalizer @inject IStringLocalizer<LeptonXResource> L @inject ITenantResolveResultAccessor TenantResolveResultAccessor @inject IOptions<AbpMultiTenancyOptions> MultiTenancyOptions @inject ICurrentTenant CurrentTenant @inject ThemeLanguageInfoProvider ThemeLanguageInfoProvider @inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout @{ AbpAntiForgeryManager.SetCookie(); var langDir = CultureHelper.IsRtl ? "rtl" : string.Empty; var title = $"{ViewBag.Title ?? PageLayout.Content.Title} | {BrandingProvider.AppName}".Trim('|', ' '); var languageInfo = await ThemeLanguageInfoProvider.GetLanguageSwitchViewComponentModel(); var returnUrl = System.Net.WebUtility.UrlEncode(Context.Request.GetEncodedPathAndQuery()); var logoUrl = BrandingProvider.LogoUrl == null ? null : "--lpx-logo: url(" + BrandingProvider.LogoUrl + ");"; var logoReverseUrl = BrandingProvider.LogoReverseUrl == null ? null : "--lpx-logo: url(" + BrandingProvider.LogoReverseUrl + ");"; var selectedStyle = await LeptonXStyleProvider.GetSelectedStyleAsync(); var selectedStyleFileName = CultureHelper.IsRtl ? selectedStyle + ".rtl" : selectedStyle; } <!DOCTYPE html> <html lang="@CultureInfo.CurrentCulture.Name" dir="@langDir"> <head> @await Component.InvokeLayoutHookAsync(LayoutHooks.Head.First, StandardLayouts.Account) <title>@title</title> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <meta charset="UTF-8" /> <meta name="description" content="@ViewBag.MetaDescription"> <link rel="icon" href="~/favicon.svg" type="image/svg+xml"> <abp-style-bundle name="@LeptonXThemeBundles.Styles.Global" /> <link href="~/Themes/LeptonX/Global/side-menu/css/bootstrap-@(selectedStyleFileName).css" type="text/css" rel="stylesheet" id="lpx-theme-bootstrap-@selectedStyle" /> <link href="~/Themes/LeptonX/Global/side-menu/css/@(selectedStyleFileName).css" type="text/css" rel="stylesheet" id="lpx-theme-color-@selectedStyle" /> @await Component.InvokeAsync(typeof(WidgetStylesViewComponent)) @await RenderSectionAsync("styles", false) @await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Account) <style> .lpx-login-bg { background-image: url('/LeptonX/images/login-pages/login-bg-img-@(selectedStyle).svg') !important; } :root .lpx-theme-light { @logoUrl } :root .lpx-theme-dark { @logoReverseUrl } :root .lpx-theme-dim { @logoReverseUrl } </style> </head> <body class="abp-account-layout lpx-theme-@selectedStyle"> @await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Account) <div class="container-fluid p-0 overflow-hidden"> @await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Account) <div class="lpx-login-area"> <div class="lpx-login-bg"> <div class="d-flex flex-column justify-content-center min-vh-100"> <div class="row"> <div class="col-xxl-5 col-lg-7 col-md-8 col-11 mx-auto position-relative py-4"> @if (BrandingProvider.LogoUrl.IsNullOrEmpty()) { <div class="lpx-logo-container lpx-login-brand-text"> <div class="lpx-brand-logo lpx-login-logo mx-auto"></div> <div class="lpx-brand-name lpx-login-name mx-auto">@BrandingProvider.AppName</div> </div> } else { <div class="lpx-brand-logo lpx-login-logo mb-3 mx-auto"></div> } <div class="card mx-auto" style="max-width: 30rem;"> <div class="card-body p-3 p-sm-4"> <div class="align-items-start d-flex justify-content-between mb-2"> <h2 class="lpx-main-title lpx-login-title m-0 me-auto"> @PageLayout.Content.Title @* TODO: Find a better text here. *@</h2> <div class="dropdown btn-group ms-auto" aria-labelledby="languageDropdown"> <button class="btn btn-sm btn-light dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <i class="bi bi-translate me-1"></i> @languageInfo.CurrentLanguage.DisplayName </button> <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenuButton1" style=""> @foreach (var language in languageInfo.Languages) { var twoLetterLanguageName = new CultureInfo(language.CultureName).TwoLetterISOLanguageName.ToUpperInvariant(); var url = Url.Content($"~/Abp/Languages/Switch?culture={language.CultureName}&uiCulture={language.UiCultureName}&returnUrl={returnUrl}"); <li> <a href="@url" class="dropdown-item" data-lpx-language-option="@twoLetterLanguageName">@language.DisplayName / @twoLetterLanguageName</a> </li> } </ul> </div> </div> <hr /> @await Component.InvokeAsync(typeof(PageAlertsViewComponent)) @if (MultiTenancyOptions.Value.IsEnabled && (TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName) == true || TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(QueryStringTenantResolveContributor.ContributorName) == true)) { <div> <div class="row"> <div class="col"> <span style="font-size: .8em;" class="text-uppercase text-muted">@MultiTenancyStringLocalizer["Tenant"]</span><br /> <h6 class="m-0 d-inline-block"> @if (CurrentTenant.Id == null) { <span> @MultiTenancyStringLocalizer["NotSelected"] </span> } else { <strong> @(CurrentTenant.Name ?? CurrentTenant.Id.Value.ToString()) </strong> } </h6> </div> <div class="col-auto"> <a id="AbpTenantSwitchLink" href="#" class="btn btn-sm btn-outline-primary">@MultiTenancyStringLocalizer["Switch"]</a> </div> </div> </div> <hr /> } @RenderBody() </div> @* @await Html.PartialAsync("~/Themes/LeptonX/Layouts/Account/_Footer.cshtml") *@ </div> </div> </div> </div> </div> </div> @await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Account) </div> <abp-script-bundle name="@LeptonXThemeBundles.Scripts.Global" /> <abp-script src="~/Abp/ApplicationLocalizationScript?cultureName=@CultureInfo.CurrentUICulture.Name"/> <abp-script src="~/Abp/ApplicationConfigurationScript"/> <abp-script src="~/Abp/ServiceProxyScript"/> @await Component.InvokeAsync(typeof(WidgetScriptsViewComponent)) @await RenderSectionAsync("scripts", false) @await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Account) </body> </html>
When we try the existing code, language switch and tenant switch do not work
Version:7.4.2
Thanks for your suggestion. It is a big deal to update to abp for us for now. I must convice many people for it. If there is a solution for 7.4.x, I would like to hear it.