Open Closed

AuditLog remove MaxLength constraint on OriginalValue and New Value from EntityPropertyChanged #3625


User avatar
0
p.j.keukens created

If you're creating a bug/problem report, please include followings:

  • ABP Framework version: v5.3.0 (Commercial)
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no

Hi,

We have created an entity with a field where we store a JSON object. On this entity we also use AuditLogging which is very important to us. The field where we store the JSON object is of type VARCHAR(MAX). When a change is written in the audit log the JSON is capped to 512 characters as the field "OriginalValue" and "NewValue" in the table "AbpEntityPropertyChanges" are only VARCHAR(512).

We changed the entity configuration to the config below, created a migration and applied changes to the database:

        builder.Entity< Volo.Abp.AuditLogging.EntityPropertyChange >().Property(x => x.OriginalValue).Metadata.RemoveAnnotation("MaxLength");
        builder.Entity< Volo.Abp.AuditLogging.EntityPropertyChange >().Property(x => x.NewValue).Metadata.RemoveAnnotation("MaxLength");
        builder.Entity< Volo.Abp.AuditLogging.EntityPropertyChange >().Property(x => x.OriginalValue).HasColumnType("nvarchar(max)");
        builder.Entity< Volo.Abp.AuditLogging.EntityPropertyChange >().Property(x => x.NewValue).HasColumnType("nvarchar(max)");

Also we changed the MaxNewValueLength and MaxOriginalValueLength to 1.000.000

        EntityPropertyChangeConsts.MaxNewValueLength = 1000000;
        EntityPropertyChangeConsts.MaxOriginalValueLength = 1000000;

In the Constructor (shown in codeblock below) of the EntityPropertyChange it truncates the value based upon MaxNewValueLength and MaxOriginalValueLength so setting it to 1000000 should store all info but in the database the original and new value are still 512 characters. Is there another place where the data is truncated? How can I fix this so that the full JSON object can be stored in the audit log?

public EntityPropertyChange(
        IGuidGenerator guidGenerator,
        Guid entityChangeId,
        EntityPropertyChangeInfo entityChangeInfo,
        Guid? tenantId = null)
    {
        Id = guidGenerator.Create();
        TenantId = tenantId;
        EntityChangeId = entityChangeId;
        NewValue = entityChangeInfo.NewValue.Truncate(EntityPropertyChangeConsts.MaxNewValueLength);
        OriginalValue = entityChangeInfo.OriginalValue.Truncate(EntityPropertyChangeConsts.MaxOriginalValueLength);
        PropertyName = entityChangeInfo.PropertyName.TruncateFromBeginning(EntityPropertyChangeConsts.MaxPropertyNameLength);
        PropertyTypeFullName = entityChangeInfo.PropertyTypeFullName.TruncateFromBeginning(EntityPropertyChangeConsts.MaxPropertyTypeFullNameLength);
    }

Also on the AuditLog we have a form which is multipart/form-data, this form is posted to the razorpage. In the audit log of the post we don't see all the data that is posted to the razorpage. Is there a way to show all the posted data in the audit log? We need this as 'proof' of what someone has posted. I see that when the ApplicationService is called it logs all data that is send to the ApplicationService method but we would like to log the posted data (without the posted files...)


13 Answer(s)
  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Hello,

    Truncate operation is done here: https://github.com/abpframework/abp/blob/e3e1779de6df5d26f01cdc8e99ac9cbcb3d24d3c/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EntityHistory/EntityHistoryHelper.cs#L173

    Can you also try to set EntityPropertyChangeInfo.MaxValueLength static property?

    EntityPropertyChangeInfo.MaxValueLength = 1000000
    
  • User Avatar
    0
    p.j.keukens created

    Hi,

    EntityPropertyChangeInfo.MaxValueLength is not a static property so I can't change it.

    any other way to solve this problem?

  • User Avatar
    0
    malik.masis created

    Hi, I've checked it and it seems static variable.

    Could you look at it here, please?

    Regards.

  • User Avatar
    0
    p.j.keukens created

    Hi,

    Yeah I see that realLiangshiwei has changed it yesterday from const to static. In which release will these changes be available?

    Thanks.

  • User Avatar
    0
    malik.masis created

    Hi, ABP 6.0 stable release date to September 20, 2022 FYI.

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Hi @p.j.keukens

    You can override the EntityHistoryHelper in your project to achieve solution in your app on your version.

    
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(EntityHistoryHelper))]
    public class MyEntityHistoryHelper  : EntityHistoryHelper
    {
         protected override List<EntityPropertyChangeInfo> GetPropertyChanges(EntityEntry entityEntry)
        {
            var propertyChanges = new List<EntityPropertyChangeInfo>();
            var properties = entityEntry.Metadata.GetProperties();
            var isCreated = IsCreated(entityEntry);
            var isDeleted = IsDeleted(entityEntry);
    
            foreach (var property in properties)
            {
                var propertyEntry = entityEntry.Property(property.Name);
                if (ShouldSavePropertyHistory(propertyEntry, isCreated || isDeleted) && !IsSoftDeleted(entityEntry))
                {
                    propertyChanges.Add(new EntityPropertyChangeInfo
                    {
                        NewValue = isDeleted ? null : JsonSerializer.Serialize(propertyEntry.CurrentValue).TruncateWithPostfix(YOUR_CUSTOM_VALUE),
                        OriginalValue = isCreated ? null : JsonSerializer.Serialize(propertyEntry.OriginalValue).TruncateWithPostfix(YOUR_CUSTOM_VALUE),
                        PropertyName = property.Name,
                        PropertyTypeFullName = property.ClrType.GetFirstGenericArgumentIfNullable().FullName
                    });
                }
            }
    }
    

    Replace the YOUR_CUSTOM_VALUE with your requirement.

    Also you can remove TruncateWithPostfix() method completely.

  • User Avatar
    0
    p.j.keukens created

    Hi,

    I have overridden the EntityHistoryHelper and that works, larger JSON is now stored in the table. There is still one weird thing and that is that the Created event on the entity is not audited.

    I do see the updated event when I change it (in a webpage) but the created not so much.

    Could this be because the created is in a Hangfirejob?

    Job definition:

    public class InformationWorker : HangfireBackgroundWorkerBase
    

    Entity:

    [Audited]
    public class InformationResponse : FullAuditedEntity
    

    Repository:

    public class EfCoreInformationResponseRepository : EfCoreRepository<InformationDbContext, InformationResponse>, IInformationResponseRepository
    

    Insert action:

    await informationResponseRepository.InsertAsync(new InformationResponse(details.Id, jsonData));
    

    Any ideas on why the created event is not in the audit log?

  • User Avatar
    0
    p.j.keukens created

    Okay so I created my own audited scope

        using (var informationScope = auditingManager.BeginScope())
        {
            auditingManager.Current.Log.Url = "InformationWorker";
            auditingManager.Current.Log.UserName = "Hangfire";
            auditingManager.Current.Log.HttpStatusCode = 200;
    
            ..... get entities .....        
            ..... update entity .....
            ..... create entity .....
            
            await informationScope.SaveAsync(); 
        }       
    
    

    Now this shows one action which is fine, then it shows the entity changes but only the insert has properties. The entitities that are updated don't show the changed properties, the entitychange is empty. Do I need to log them manually?

  • User Avatar
    0
    gterdem created
    Support Team Senior .NET Developer

    You can either log them manually or add to EntityHistorySelectors in AbpAuditingOptions.

  • User Avatar
    0
    p.j.keukens created

    You can either log them manually or add to EntityHistorySelectors in AbpAuditingOptions.

    @gterdem I have decorated the classes with [Audited] which should be the same as with the entityhistoryselectors isn't it?

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    You can either log them manually or add to EntityHistorySelectors in AbpAuditingOptions.

    @gterdem I have decorated the classes with [Audited] which should be the same as with the entityhistoryselectors isn't it?

    Yes, both them mean same thing. You can either use attributes or manage all of them from selectors.

    • Attribute has higher priority, if you define attribuıte it'll accepted: https://github.com/abpframework/abp/blob/c78497a4cebf1ca39e355b6b62185db4a291dc80/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs#L109

    • Selector has the lowest priority and it's checked at the end: https://github.com/abpframework/abp/blob/c78497a4cebf1ca39e355b6b62185db4a291dc80/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs#L120

    So, yes both of them can be used for the same purpose.

  • User Avatar
    0
    p.j.keukens created

    Hi,

    You guys said that the change underneath would be merged in abp 6.0.0 but I have upgraded my project to 6.0.0 and the property

    EntityPropertyChangeInfo.MaxValueLength is still a const int instead of a static int

    https://github.com/abpframework/abp/blob/745d374a5a433a12d45e2ef591e6c85265a785cb/framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityPropertyChangeInfo.cs#L18

    As I have my entities marked as audited the changed properties should show up but the audit log and the database only show the action not the properties. So the problem is still there, we need to be able to rely on the audit log.

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Yes, you're right. The PR was made to the dev branch which will be shipped in v7.0.

    So, I've picked those changes to the v6.0, it'll be included in the closest patch version (6.0.1). https://github.com/abpframework/abp/pull/14293

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11