2

I'am using the Audit.Net to track the changes. Very good libray

By using Audit.EntityFramework extension, we can ignore the properties to be track.

public class User
{
    public int Id { get; set; }
    [AuditIgnore]
    public string Password { get; set; }
    ...
}

But I have problem

  1. I'am not using Audit.EntityFramework extension. Just get the json format by using my own custom data provider. So [AuditIgnore] cannot work here.
  2. How to ignore the password property on the IdentityUser class?

Here my custom data provider

public class MyCustomDataProvider : AuditDataProvider
    {
        public override object InsertEvent(AuditEvent auditEvent)
        {
            var AuditEventInJson = auditEvent.ToJson();

            //Save into to DB;
        }
    }
Azri Zakaria
  • 1,324
  • 5
  • 23
  • 52
  • Do you mean the [`PasswordHash`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.entityframeworkcore.identityuser-4.passwordhash?view=aspnetcore-1.1#Microsoft_AspNetCore_Identity_EntityFrameworkCore_IdentityUser_4_PasswordHash) on `IdentityUser`? – thepirat000 Jan 08 '19 at 06:07
  • Yes exactly what I mean – Azri Zakaria Jan 08 '19 at 06:31
  • Ok so I guess the answer about using a custom contract resolver should work for you. – thepirat000 Jan 08 '19 at 06:54

1 Answers1

3

The ToJson() method will internally use the JSON.NET library to serialize the event and will use the default settings from the static property Audit.Core.Configuration.JsonSettings

So if you can change the code of the class containing the password, you can use the JsonIgnore attribute:

public class User
{
    [JsonIgnore]
    public string Password { get; set; }
    ...
}

Alternatively, if you cannot decorate the property, you can create a custom Contract Resolver to ignore properties generically, for example to ignore any property called "Password":

class MyCustomResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var props = base.CreateProperties(type, memberSerialization);
        return props.Where(p => p.PropertyName != "Password").ToList();
    }
}

For this to work with the Audit.NET ToJson() method, you need to set the contract resolver on the Audit.NET global configuration like this:

Audit.Core.Configuration.JsonSettings.ContractResolver = new MyCustomResolver();

A third option is to attach a Custom Action to remove the properties to ignore before the event saving takes place, for example:

Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaving, scope =>
{
    var efEvent = scope.Event.GetEntityFrameworkEvent();
    efEvent.Entries.ForEach(e => 
    { 
        e.Changes.RemoveAll(ch => ch.ColumnName == "Password");
    });
});
thepirat000
  • 12,362
  • 4
  • 46
  • 72
  • 1
    This behavior has changed starting on version 18.0.0, now the default serialization mechanism depends on the target framework. If you target .NET 5.0 or higher, the default mechanism is to use System.Text.Json. You can check the docs [here](https://github.com/thepirat000/Audit.NET#breaking-change-in-version-18) – thepirat000 Aug 17 '21 at 21:13