1

I am new to the use of audit.net. I need to audit a series of custom values from the parameters received in the action method as follows.

[AuditField("User","reqLogin.User")]              
[AuditCustom(EventTypeName =  "AccesoAction")]  
public async Task<IActionResult> Acceso(LoginRequest reqLogin)
{            
     ...
}

I have to create a CustomField with FieldName "User" and value, the value of the User attribute of parameter reqLogin (reqLogin.User).

I'm extending the AuditAttribute class, to overwrite the OnActionExecutionAsync method and add the CustomField.

public class AuditCustomAttribute : AuditAttribute
{
  public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
  {
      lock (context.ActionDescriptor.Parameters)
      {
        foreach (AuditFieldAttribute apa in context.ActionDescriptor.Parameters.Cast<ControllerParameterDescriptor>().First().ParameterInfo.Member.GetCustomAttributes<AuditFieldAttribute>())
    {
           // create CustomField and add to context
    }
}   
 return base.OnActionExecutionAsync(context, next);
}
}

Finally, in my custom AuditDataProvider class, I would audit the customFields that arrived in the auditevent field of method:

  public override object InsertEvent(AuditEvent auditEvent)

How would it be possible? Thanks

1 Answers1

1

It's not very clear what are you asking, but I guess you're using the Audit.MVC extension.

Why do you need to create a CustomField with information you already have on the ActionParameters?

Also I don't think you need to subclass the AuditAttribute being that there is already a CustomAction mechanism you can use, for example:

Audit.Core.Configuration.AddOnCreatedAction(scope =>
{
    var action = scope.GetMvcAuditAction();
    var login = action.ActionParameters.FirstOrDefault(p => p.Key == "reqLogin").Value as LoginRequest;
    scope.SetCustomField("User", login.User);
});
thepirat000
  • 12,362
  • 4
  • 46
  • 72
  • Thanks for the reply. Yes, I'm using Audit.MVC. Using scope.SetCustomField in Action is a possibility to solve the problem but, it is possible to overwrite OnActionExecutionAsync to add custom parameters that can intercept in a AuditDataProvider custom class? – user3157675 May 30 '19 at 06:39
  • Yes you can. But I guess the problem to solve for your approach would be to translate the string `"reqLogin.User"` into the property value of `reqLogin.User` – thepirat000 May 30 '19 at 16:16
  • Hi. By reflection I can obtain the values of the parameters. That is already solved, it was just an example. Is correct to use Audit.Core.Configuration.AddOnCreatedAction(scope =>...) in the method OnActionExecutionAsync? Thanks so much for the help – user3157675 May 31 '19 at 06:27
  • No it is not correct. The `AddOnCreatedAction` should be called just once, i.e. on your startup code – thepirat000 May 31 '19 at 15:09
  • ok, then, what is the best way to add custom field in the method OnActionExecutionAsync?. I'm seeing how customfield is added from the controller's Action method and from the method OnActionExecutionAsync, in the same scope. Thanks – user3157675 May 31 '19 at 17:10
  • You can get current scope with `AuditAttribute.GetCurrentScope(httpContext);`, but since the AuditScope is created, saved and disposed within the OnActionExecutionAsync, you will not be able to add custom fields there to be persisted. What do you need from the ActionExecutingContext that is not on the audit event? – thepirat000 May 31 '19 at 19:23
  • Hi. My main problem is that I have to allow customfield to be added with information about certain parameters of an Action method of the controller. I have to add this information from an ActionFilterAttribute class, applying reflection to the parameters of the Action method because I can not do it by adding code within the action method (such as auditScope.SetCustomField (..)) for this type of information – user3157675 May 31 '19 at 21:47
  • I also have to allow other customfields to be added as the result of performing the operation (incorrect 0, error produced, 1 correct execution) or any other parameter, in this case, adding code within the action method of the controller, as indicated in the examples. Now I am testing the following: var controller = context.Controller as Controller; var scope = controller .GetCurrentAuditScope();, but in OnResultExecutionAsync (...) – user3157675 May 31 '19 at 21:48
  • So it looks like `AddOnCreatedAction`/`AddOnSavingAction` fits your needs. You can access the parameters and result there, to add any custom field you want. – thepirat000 May 31 '19 at 21:52
  • Ok, thanks for the help, I will try to use the event AddOnSavingAction. Thanks a lots – user3157675 May 31 '19 at 22:06