Your JSON shows two different configuration shapes, but the one ABP’s Azure Event Bus expects is under Azure:EventBus, not top-level EventBus, and not Abp:EventBus:Azure (in your version/module).
That’s why ABP still ends up with topicName = null at startup: it’s not reading the keys you think it is.
Use this exact section (and remove the others to avoid confusion):
{
"Azure": {
"ServiceBus": {
"Connections": {
"Default": {
"ConnectionString": "Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..."
}
}
},
"EventBus": {
"ConnectionName": "Default",
"SubscriberName": "email-subscription",
"TopicName": "notification-event"
}
}
}
Then delete these sections entirely (they are not used by Volo.Abp.EventBus.Azure initialization and can mislead you during troubleshooting):
"EventBus": { ... },
"Abp": { "EventBus": { "Azure": { ... } } }
Also, in your posted config you have:
"ConnectionString": ""
Even after fixing TopicName, you will fail later because the connection string is empty. Put a real Azure Service Bus connection string there.
If you want the host to start without Azure Service Bus at all (e.g., in local dev), you must remove the dependency on Volo.Abp.EventBus.Azure / AbpEventBusAzureModule from that host; otherwise ABP will always try to initialize it on startup.
(Validated reference relevant to Azure Service Bus EventBus config format used by ABP support)
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
AzureServiceBusMessageConsumer with a null topicName:AzureServiceBusMessageConsumer.Initialize(String topicName, String subscriptionName, String connectionName)
...
ArgumentNullException: Value cannot be null. (Parameter 'topicName')
So your host app is starting with Volo.Abp.EventBus.Azure enabled, but the Azure EventBus TopicName is not configured (or not being read).
HttpApi.Host, AuthServer, etc.) appsettings.json / environment-specific file:{
"Azure": {
"ServiceBus": {
"Connections": {
"Default": {
"ConnectionString": "Endpoint=sb://<yournamespace>.servicebus.windows.net/;SharedAccessKeyName=...;SharedAccessKey=..."
}
}
},
"EventBus": {
"ConnectionName": "Default",
"SubscriberName": "<YourApp_Subscriber>",
"TopicName": "<YourTopicName>"
}
}
}
Notes (based on how ABP initializes the consumer):
Azure:EventBus:TopicName must be non-empty.
Azure:EventBus:SubscriberName is also required for subscriptions (keep it non-empty).
Azure:EventBus:ConnectionName must match a key under Azure:ServiceBus:Connections.
Also ensure you are not accidentally “losing” config values due to environment overrides:
appsettings.Development.json, appsettings.Production.json, Kubernetes env vars, etc., confirm none of them overwrite Azure:EventBus:TopicName with an empty value.If you don’t intend to use Azure Service Bus in this host, remove/disable the Azure event bus module from that host’s module dependencies (so AbpEventBusAzureModule doesn’t run). Otherwise ABP will always try to initialize it during application startup.
Sources (validated):
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
What you want is PathBase / virtual directory hosting for each app in a tiered MVC solution:
https://localhost:44318/authhttps://localhost:44392/portal/apihttps://localhost:44374/portalIn ABP (including v9.3.6), the reliable way to do this is:
UsePathBase) for each application./portal/... and /auth/..../authIn AuthServer (YourProject.AuthServer) add PathBase early in the pipeline:
// in OnApplicationInitialization / Program.cs pipeline
app.UsePathBase("/auth");
Then set AuthServer self URL accordingly in appsettings.json:
"App": {
"SelfUrl": "https://localhost:44318/auth"
}
Also ensure the OIDC issuer/authority used by clients points to:
https://localhost:44318/auth/portal/apiIn HttpApi.Host add:
app.UsePathBase("/portal/api");
Set:
"App": {
"SelfUrl": "https://localhost:44392/portal/api"
}
If your MVC UI calls this API via remote services, set the remote service base URL (commonly in Web project) to include /portal/api.
/portalIn Web (MVC UI) add:
app.UsePathBase("/portal");
Set:
"App": {
"SelfUrl": "https://localhost:44374/portal"
}
And update the AuthServer authority used by Web:
"AuthServer": {
"Authority": "https://localhost:44318/auth",
"RequireHttpsMetadata": "false"
}
Because you changed the base paths, the redirect endpoints change too:
https://localhost:44374/portal/signin-oidchttps://localhost:44374/portal/signout-callback-oidchttps://localhost:44392/portal/api/swagger/oauth2-redirect.htmlSo you must update your OpenIddict application/client configuration in the database (or via ABP data seeding / DbMigrator configuration) to use the new URLs.
For non-technical requests like arranging a meeting, please contact us at:
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Make your entity audited (if it isn’t already)
Use an audited base entity such as AuditedAggregateRoot<TKey> / FullAuditedAggregateRoot<TKey> (or their non-aggregate variants), so the entity actually has the audit properties.
Change the generated DTO base class to an audited DTO
Instead of inheriting from EntityDto<TKey>, inherit from one of:
AuditedEntityDto<TKey> (includes CreationTime, CreatorId, LastModificationTime, LastModifierId)FullAuditedEntityDto<TKey> (adds DeletionTime, DeleterId, IsDeleted)Example:
using System;
using Volo.Abp.Application.Dtos;
public class MyEntityDto : AuditedEntityDto<Guid>
{
// your custom properties...
// CreationTime is already available from AuditedEntityDto<Guid>
}
Ensure your AutoMapper mapping exists
Your mapping CreateMap<MyEntity, MyEntityDto>() will map CreationTime automatically as long as the DTO has that property via the base class.
Add the column/field in the UI
creationTime.creationTime.
This is usually the only “UI-layer” manual step you need once the DTO exposes the property.In ABP, the auditing property is typically named CreationTime (not CreatedTime). So if you were looking for CreatedTime, you won’t see it unless you created your own property. Use CreationTime in DTO/UI.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Please use the official support ticket page to continue with ticket #10312 (add the requested details/logs, follow up with replies, or ask for status updates). I can’t access or act on tickets from here, and ABP support staff can only continue the process inside that ticket thread.
If you need to escalate or you’ve run out of question credits / need account-level help, contact ABP via:
(Your ticket link is reachable: https://abp.io/support/questions/10312/Error-when-Save-and-Generate-Class-with-Abp-Suite)
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
CloverleafCMS_PR_Identity indicates the consumer side (Identity service) is not processing the tenant-created event, or it processes it but the seed/migration fails (often with a DB connection/timeout issue in production).Check Identity service logs right after tenant creation
Verify the distributed event infrastructure is healthy
Most common real cause in production: seeding/migration fails due to DB connection/timeout
If you are using “shared database” (no per-tenant connection string)
Confirm tenant DB (or schemas) are created/migrated and seed completed
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
In ABP 9.0.x (Angular + OpenIddict), domain/subdomain tenant resolution commonly breaks the OIDC code flow unless you also enable wildcard domain support for OpenIddict and ensure the issuer/redirect/cors/client configuration matches the tenant-specific domain(s). Symptoms are exactly what you described: infinite login loop (Angular keeps trying to complete code flow but token/config validation fails) or tenant login works for host only.
The community article you followed includes the key ABP-side requirement (wildcard support) via AbpOpenIddictWildcardDomainOptions. You must apply it in ABP 9.0.4 too (in your *.HttpApi.Host module), and you must also make sure your client URLs / redirect allowed URLs / CORS origins are compatible with subdomains.
In your HttpApiHostModule (ABP 9.0.4), configure both:
using Volo.Abp.MultiTenancy;
using Volo.Abp.OpenIddict.WildcardDomains;
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpOpenIddictWildcardDomainOptions>(options =>
{
options.EnableWildcardDomainSupport = true;
// IMPORTANT: Add formats matching your real UI domain(s)
// Example (production):
options.WildcardDomainsFormat.Add("https://{0}.dentpalqaaumtech.org");
// Example (local):
// options.WildcardDomainsFormat.Add("http://{0}.multitenancydemo.local:4200");
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpTenantResolveOptions>(options =>
{
options.AddDomainTenantResolver("{0}.dentpalqaaumtech.org");
// local example: options.AddDomainTenantResolver("{0}.multitenancydemo.local");
});
}
If your localhost custom domain testing is done over HTTP, you must also disable the transport security requirement for OpenIddict server in DEBUG (as shown in the article), otherwise the flow will fail/loop:
#if DEBUG
PreConfigure<OpenIddictServerBuilder>(options =>
{
options.UseAspNetCore().DisableTransportSecurityRequirement();
});
#endif
{0} pattern (and HTTPS requirement must match)Your Angular environment.ts (or dynamic env) must match the tenant domain pattern you use:
application.baseUrl should be https://{0}.dentpalqaaumtech.org (or your localhost domain pattern)oAuthConfig.redirectUri should usually be the same baseUrl patternrequireHttps: falseThis is required so Angular computes tenant context correctly from the URL and completes the code flow without bouncing.
This almost always indicates redirect uri / CORS / authority mismatch between:
https://tenant1.dentpalqaaumtech.org)RedirectAllowedUrls, client redirect URIs, CORS origins)Ensure your appsettings.json has tenant-compatible entries (examples):
App:SelfUrl should be the actual backend URL (not tenant-subdomain unless you truly host backend per-tenant)App:CorsOrigins should include your tenant subdomain pattern as supported by ABP’s wildcard cors helpers (don’t invent formats OpenIddict/ABP can’t parse)App:RedirectAllowedUrls must include tenant UI domains that will receive the authorization code callback (e.g. https://*.dentpalqaaumtech.org style rules depending on your setup)Also, after changing these, run DbMigrator (or otherwise update OpenIddict/clients in DB) so redirect URI/cors/client settings are not stale.
In ABP Angular, the app will try to exchange the code for tokens and then load the application configuration. If issuer/redirect/CORS/wildcard-domain support is not correctly aligned for the tenant domain, the exchange/config call fails, and Angular navigates back to login again → loop.
This behavior is consistent with ABP support cases where a misconfigured OpenIddict certificate or issuer also causes loops, but in domain-tenant scenarios the most frequent root cause is missing wildcard domain support and/or mismatched allowed redirect/CORS/client settings.
Sources (validated)
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
AbpApplicationConfigurationAppService.GetAsync() (application configuration endpoint). If that call fails (typically 401/403/500 or a blocked request), ABP shows the generic modal “An error has occurred! Error detail not sent by server.”.Do the following fixes (they are safe and align with ABP Angular deployment expectations):
Ensure your Angular site serves index.html for deep links (SPA rewrite)
web.config in your Angular build output (same folder as index.html) that rewrites all non-file, non-folder routes to /index.html.Ensure the Angular app’s environment.prod.ts points to the correct backend URL (HTTPS)
apis.default.url must be the exact public URL of your Host (normally https://...).http:// (or wrong host) which gets redirected/blocked, while later calls appear fine due to cached baseUrl/config.If UI and Host are on different origins, fix CORS on the Host
App:CorsOrigins to include the Angular Web App origin (e.g., https://your-angular-site.azurewebsites.net) exactly.App:RedirectAllowedUrls contains your Angular URL (important for auth redirects).Verify the first failing request in the browser Network tab
Sources (validated)
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
abp logout
abp login
If it still shows “Please login with your account”, this is typically not a framework/runtime issue but a Suite/CLI authentication session problem. In that case, please open a commercial support ticket so the team can check your ABP account/session on the server side:
Links (docs):
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
app.MapAbpStaticAssets() during startup. In ABP 9.x this middleware writes a static web assets endpoints manifest file (e.g. Volo.Abp.AspNetCore.staticwebassets.endpoints.json) to the content root./app, but the process user doesn’t have write permission there (common when running as a non-root user and/or when /app is from a read-only image layer), so startup fails with:
Access to the path '/app/Volo.Abp.AspNetCore.staticwebassets.endpoints.json' is denied./app writable for the container userUpdate your Dockerfile so the runtime user can write to /app:
# ... your existing build/publish stages ...
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
COPY --from=publish /app/publish .
# If you run as a non-root user, ensure /app is owned by that user
# (UID/GID depends on your image/user setup)
RUN chown -R 1000:1000 /app
USER 1000
ENTRYPOINT ["dotnet", "Approach.Web.dll"]
If you’re using ABP’s default non-root approach but with a different UID, adjust 1000 accordingly.
If you can’t change the image, you can ensure /app is writable by mounting a volume (note: this can hide files in /app if you mount over it, so it must be used carefully; generally prefer the Dockerfile fix):
services:
web:
volumes:
- web_app_data:/app
volumes:
web_app_data:
If you are not using ABP virtual-file-system UI assets in this host, you can remove/comment the call:
// app.MapAbpStaticAssets();
(Only do this if you confirm your UI still serves required static/virtual assets correctly.)
Links:
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.