- ABP Framework version: v8.2.0-rc.1
- UI Type: Blazor WASM
- Database System: EF Core (SQL Server)
- Tiered (for MVC) or Auth Server Separated (for Angular): no
- Exception message and full stack trace: none
- Steps to reproduce the issue: 1 Create a new abp blazor wasm solution. 2 Create the following entity "Book" using Abp Suite:
public class Book : AuditedEntity<int>, IHasConcurrencyStamp
{
[NotNull]
public virtual string Title { get; set; }
public virtual int Pages { get; set; }
public virtual DateOnly? PublishDate { get; set; }
public string ConcurrencyStamp { get; set; }
protected Book()
{
}
public Book(string title, int pages, DateOnly? publishDate = null)
{
ConcurrencyStamp = Guid.NewGuid().ToString("N");
Check.NotNull(title, nameof(title));
Title = title;
Pages = pages;
PublishDate = publishDate;
}
}
3 Add the data annotations so it would audit only the "PublishDate" property as by the documentation (https://docs.abp.io/en/abp/latest/Audit-Logging#enable-disable-for-entities-properties)
[DisableAuditing]
public class Book : AuditedEntity<int>, IHasConcurrencyStamp
{
[NotNull]
public virtual string Title { get; set; }
public virtual int Pages { get; set; }
[Audited]
public virtual DateOnly? PublishDate { get; set; }
public string ConcurrencyStamp { get; set; }
protected Book()
{
}
public Book(string title, int pages, DateOnly? publishDate = null)
{
ConcurrencyStamp = Guid.NewGuid().ToString("N");
Check.NotNull(title, nameof(title));
Title = title;
Pages = pages;
PublishDate = publishDate;
}
}
4 Create a record for the entity 5 Edit the property "Title" of the record 6 In the "Audit logs" page then "Entity Changes" notice how an empty record has been created
It would be helpful if it created the record only when an Audited property is changed.
7 Answer(s)
-
0
hi
The
Audit logs
andEntity Changes
are two concepts.5 Edit the property "Title" of the record
Will create an
audit log
entity and won't create anyEntity Changes
entities. -
0
Hi,
Can you elaborate more? Both these concept are under "Audit Logging" in the documentation (https://docs.abp.io/en/abp/latest/Audit-Logging)
Looking through the Database the reason for the blank record is that it created a record for the table "AbpEntityChanges" but no record for the "AbpEntityPropertyChanges" (since there were no changes to the audited properties).
I also tried inverting the data annotation like it is explained in the documentation but the behavior stays the same.
If there were no changes to the audited property of the entity (no "AbpEntityPropertyChanges" records created) it would be useful if it did not create a record for the "AbpEntityChanges" table.
-
0
hi
If there were no changes to the audited property of the entity (no "AbpEntityPropertyChanges" records created) it would be useful if it did not create a record for the "AbpEntityChanges" table.
This is the default behavior but you can override the
AuditingStore
to change it.eg remove the
EntityChange
fromAuditLog
if there is noEntityPropertyChange
https://github.com/abpframework/abp/blob/dev/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditingStore.cs#L52-L59
-
0
hi,
Can you please provide us with the code needed to make this behavior change?
Also, quoting the documentation:
In some cases, you may want to save a few properties but ignore all others. Writing [DisableAuditing] for all the other properties would be tedious. In such cases, use [Audited] only for the desired properties and mark the entity with the [DisableAuditing] attribute
I would expect that if I disable auditing on the entity and enable auditing only on a property I should have a record in AuditingStore only if the property has changed.
If this is not a bug for you then I am going to ask you to update the documentation to better clarify how it works.
Thanks.
-
0
hi
You can add this class to your
Domain
layer. The key code isauditLog.EntityChanges.RemoveAll(x => x.PropertyChanges.Count == 0);
using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.Auditing; using Volo.Abp.AuditLogging; using Volo.Abp.DependencyInjection; using Volo.Abp.Uow; namespace MyCompanyName.MyProjectName; [Dependency(ReplaceServices = true)] [ExposeServices(typeof(AuditingStore), typeof(IAuditingStore))] public class MyAuditingStore : AuditingStore { public MyAuditingStore( IAuditLogRepository auditLogRepository, IUnitOfWorkManager unitOfWorkManager, IOptions<AbpAuditingOptions> options, IAuditLogInfoToAuditLogConverter converter) : base(auditLogRepository, unitOfWorkManager, options, converter) { } protected async override Task SaveLogAsync(AuditLogInfo auditInfo) { using (var uow = UnitOfWorkManager.Begin(true)) { var auditLog = await Converter.ConvertAsync(auditInfo); auditLog.EntityChanges.RemoveAll(x => x.PropertyChanges.Count == 0); await AuditLogRepository.InsertAsync(auditLog); await uow.CompleteAsync(); } } }
-
0
hi,
It works thanks.
-
0
Great