No, you do not need to create a separate module or your own DbContext for auditing when you use the built-in AbpAuditLoggingDbContext. You also do not need a custom IAuditingStore. Use the provided Audit Logging module and its EF Core integration.
Minimal, working setup to persist audit logs in a separate MSSQL database with a single DbMigrator:
[DependsOn(
typeof(Volo.Abp.EntityFrameworkCore.SqlServer.AbpEntityFrameworkCoreSqlServerModule),
typeof(Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingEntityFrameworkCoreModule)
)]
public class YourAppEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDbContextOptions>(options =>
{
// Set provider globally (covers AbpAuditLoggingDbContext too)
options.UseSqlServer();
// or explicitly per context if you prefer
options.Configure<Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingDbContext>(c =>
{
c.UseSqlServer();
});
});
}
}
{
"ConnectionStrings": {
"Default": "Server=.;Database=MainDb;Trusted_Connection=True;TrustServerCertificate=true",
"AbpAuditLogging": "Server=.;Database=AuditDb;Trusted_Connection=True;TrustServerCertificate=true"
}
}
Put this in the appsettings.json of:
dotnet ef migrations add Init_Audit_Logging \
--context Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingDbContext
If design-time discovery fails, add a design-time factory for AbpAuditLoggingDbContext pointing to the AbpAuditLogging connection.
dotnet run --project src/YourApp.DbMigrator
Configure<AbpAuditingOptions>(o => { o.IsEnabled = true; });
app.UseAuditing();
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.
A) Fix the JSON error on Create/View Form
public class MyFormInputDto
{
// Bad: public Type GridDefinitionType { get; set; }
[DisableValidation] // avoids recursive validation and reflection-related exceptions
[JsonIgnore] // make sure it's not serialized over HTTP
public Type GridDefinitionType { get; set; }
}
B) Prevent random re-login when accessing the MVC sub-module from Angular
ConfigureApplicationCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
C) Multi-tenancy consistency (tenant login in forms module)
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost
});
D) When hosting SignalR (used by Forms notifications) behind YARP
app.Use(async (ctx, next) =>
{
var accessToken = ctx.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken) && ctx.Request.Path.StartsWithSegments("/signalr-hubs"))
{
ctx.Request.Headers["Authorization"] = "Bearer " + accessToken;
}
await next();
});
E) CORS and Redirects (Angular + MVC)
F) Quick verification steps
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.
Example: Map authorization/validation/identity namespaces to your resource and provide translations.
csharp // Domain.Shared module [DependsOn( typeof(AbpExceptionHandlingModule), typeof(AbpValidationModule), typeof(AbpAuthorizationModule), typeof(AbpIdentityDomainSharedModule) )] public class MyProjectDomainSharedModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { Configure<AbpLocalizationOptions>(options => { options.Resources .Add<MyProjectResource>("en") .AddVirtualJson("/Localization/MyProject"); });
Configure<AbpExceptionLocalizationOptions>(options =>
{
// Map exception code namespaces to your resource
options.MapCodeNamespace("Volo.Abp.Authorization", typeof(MyProjectResource));
options.MapCodeNamespace("Volo.Abp.Validation", typeof(MyProjectResource));
options.MapCodeNamespace("Volo.Abp.Identity", typeof(MyProjectResource));
// add more if needed
});
}
}
en.json { "culture": "en", "texts": { "Volo.Abp.Authorization:DefaultErrorMessage": "The user represented by the token is not allowed to perform the requested action.", "Volo.Abp.Authorization:Forbidden": "Forbidden" } }
tr.json { "culture": "tr", "texts": { "Volo.Abp.Authorization:DefaultErrorMessage": "Belirteçle temsil edilen kullanıcı bu işlemi yapmaya yetkili değil.", "Volo.Abp.Authorization:Forbidden": "Yasak" } }
Notes:
Optional: Customize the displayed title/text shape for MVC 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.
Addressing your points:
A) “If we refer to other Application layer Contracts, lead to static access storage”
B) “Additional load to other Application permissions”
C) “Move XXXPermissionDefinitionProvider to Application layer”
D) Recommended setup
Configure<PermissionManagementOptions>(options =>
{
options.ISaveStaticPermissionsToDatabase = true;
options.IsDynamicPermissionStoreEnabled = false;
});
E) Troubleshooting tips
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.
Why DbMigrator didn’t create the audit DB
Fix step-by-step
[DependsOn(
typeof(Volo.Abp.EntityFrameworkCore.SqlServer.AbpEntityFrameworkCoreSqlServerModule),
typeof(Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingEntityFrameworkCoreModule)
)]
public class YourAppEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDbContextOptions>(options =>
{
// Global default or per-context config
options.UseSqlServer();
options.Configure<Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingDbContext>(c =>
{
c.UseSqlServer();
});
});
}
}
{
"ConnectionStrings": {
"Default": "Server=.;Database=MainDb;Trusted_Connection=True;TrustServerCertificate=true",
"AbpAuditLogging": "Server=.;Database=AuditDb;Trusted_Connection=True;TrustServerCertificate=true"
}
}
Add the AbpAuditLogging.EntityFrameworkCore package reference to the project where you keep migrations (commonly the EFCore or DbMigrator project references it).
Make sure the project builds and can resolve the context at design-time. Typically you either:
Example design-time factory (only for migration generation):
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System.IO;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
public class AbpAuditLoggingDbContextFactory : IDesignTimeDbContextFactory<AbpAuditLoggingDbContext>
{
public AbpAuditLoggingDbContext CreateDbContext(string[] args)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false)
.AddEnvironmentVariables()
.Build();
var builder = new DbContextOptionsBuilder<AbpAuditLoggingDbContext>()
.UseSqlServer(configuration.GetConnectionString("AbpAuditLogging"));
return new AbpAuditLoggingDbContext(builder.Options);
}
}
dotnet ef migrations add Init_Audit_Logging --context Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingDbContext
Notes:
dotnet run --project src/YourApp.DbMigrator
Configure<AbpAuditingOptions>(options =>
{
options.IsEnabled = true;
options.EntityHistorySelectors.AddAllEntities();
});
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
app.UseAuditing();
}
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-modal
[(visible)]="isOpen"
[options]="{ windowClass: 'my-wide-modal', size: 'xl' }"
>
<ng-template #abpHeader>My Wide Editor</ng-template>
<ng-template #abpBody> ... complex content ... </ng-template>
<ng-template #abpFooter>
<abp-button (click)="isOpen = false">Close</abp-button>
</ng-template>
</abp-modal>
Notes:
ngb-modal-window.my-wide-modal .modal-dialog {
max-width: 90vw !important; /* or a fixed px width */
width: 90vw; /* ensure it expands */
margin: 1.5rem auto; /* optional: adjust centering/margins */
}
/* Optionally control body height/scrolling if needed */
ngb-modal-window.my-wide-modal .modal-content {
height: calc(100vh - 3rem);
}
Why global? NgbModal renders outside the component tree, so ViewEncapsulation styles won’t reach it. A unique windowClass ensures the rule applies only to that single modal, not globally.
About dialogClass/modalClass inputs
Is passing custom NgbModal options supported?
If you prefer a CSS-only approach without options
Recommended alternative for very complex editors
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 happened
Immediate fix (so you can continue working)
Make the failure visible next time
CI/CD and production guidance
Feature request acknowledgement
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.
The AbpAuditLoggingDbContext uses a predefined connection string name: "AbpAuditLogging". If you don’t define it, it falls back to the "Default" connection string.
To store audit logs in a separate database, add a dedicated connection string named AbpAuditLogging in your configuration. No extra wiring to the DbContext is needed beyond using the EF Core provider for that context.
Steps:
{
"ConnectionStrings": {
"Default": "Server=.;Database=MainDb;Trusted_Connection=True;TrustServerCertificate=true",
"AbpAuditLogging": "Server=.;Database=AuditDb;Trusted_Connection=True;TrustServerCertificate=true"
}
}
[DependsOn(
typeof(Volo.Abp.EntityFrameworkCore.SqlServer.AbpEntityFrameworkCoreSqlServerModule),
typeof(Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingEntityFrameworkCoreModule)
)]
public class YourAppEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDbContextOptions>(options =>
{
// Global provider or per-context
options.UseSqlServer();
options.Configure<Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingDbContext>(c =>
{
c.UseSqlServer();
});
});
}
}
Why this works:
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.
You’re right: AbpDbConnectionOptions.Databases.Configure(...).MappedConnections.Add(...) expects connection name strings, not DbContext types. Use the module’s connection name for Audit Logging.
Correct configuration for storing Audit Logs in a separate database:
{
"ConnectionStrings": {
"Default": "Server=.;Database=MainDb;Trusted_Connection=True;TrustServerCertificate=true",
"AuditLogging": "Server=.;Database=AuditDb;Trusted_Connection=True;TrustServerCertificate=true"
}
}
Configure<AbpDbConnectionOptions>(options =>
{
options.Databases.Configure("AuditLogging", db =>
{
// Map module connection names (strings), not types
db.MappedConnections.Add("AbpAuditLogging");
});
});
Configure<AbpDbContextOptions>(options =>
{
options.UseSqlServer();
options.Configure<Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingDbContext>(opt =>
{
opt.UseSqlServer();
});
});
[DependsOn(
typeof(Volo.Abp.EntityFrameworkCore.SqlServer.AbpEntityFrameworkCoreSqlServerModule),
typeof(Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingEntityFrameworkCoreModule)
)]
public class YourAppEntityFrameworkCoreModule : AbpModule
{
}
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.
Use a single DbMigrator to migrate both databases (your main “Default” DB and the separate Audit Logging DB). ABP’s DbMigrator already supports multiple DbContexts and multiple databases; you only need to map the AbpAuditLoggingDbContext to its own connection and ensure its migrations are included.
Steps:
{
"ConnectionStrings": {
"Default": "Server=.;Database=MainDb;Trusted_Connection=True;TrustServerCertificate=true",
"AuditLogging": "Server=.;Database=AuditDb;Trusted_Connection=True;TrustServerCertificate=true"
}
}
[DependsOn(
typeof(AbpEntityFrameworkCoreSqlServerModule),
typeof(AbpAuditLoggingEntityFrameworkCoreModule)
)]
public class YourAppEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDbContextOptions>(options =>
{
options.UseSqlServer();
options.Configure<AbpAuditLoggingDbContext>(c => c.UseSqlServer());
});
Configure<AbpDbConnectionOptions>(options =>
{
options.Databases.Configure("AuditLogging", db =>
{
db.MappedConnections.Add(typeof(AbpAuditLoggingDbContext));
});
});
}
}
dotnet ef migrations add "Init_Audit_Logging" --context AbpAuditLoggingDbContext
Ensure the design-time factory (IDesignTimeDbContextFactory) for AbpAuditLoggingDbContext reads the “AuditLogging” connection.
cd your-solution/src/YourApp.DbMigrator
dotnet run
It should apply migrations to MainDb and AuditDb respectively.
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.