2

I think what I want to do is not possible. However, I would like to make sure that it is indeed not possible.

I use Audit.Net as a framework to add auditing to a system that has already been completed. There are many different objects that may be sent for auditing. I have to get hold of the properties of those objects and send them to the database. In some cases, I would want the old values and the new values, and therefore I use the Target property of AuditEvent, otherwise if I just need the new values I use the CustomField property.

Is there any way to make the following more generic, so that I don't have to repeat these lines for each type of object like SimpleResult, LeaveRequest, Incident etc? There is unfortunately no commonality between the objects being audited.

SimpleResult objOld = JsonConvert.DeserializeObject<SimpleResult>(auditEvent.Target.SerializedOld.ToString());                      

SimpleResult objNew = JsonConvert.DeserializeObject<SimpleResult>(auditEvent.Target.SerializedNew.ToString());                       

if (auditEvent.Target.Type.ToString() == "SimpleResult")
{
       InsertTargetObjectFields<SimpleResult>(objOld, objNew, auditControlTableID, auditEvent);                           
}

Here is where I get hold of the properties and send them off to the database:

 public void InsertTargetObjectFields<T>(T objOld, T objNew, int? auditControlTableID, AuditEvent auditEvent)
    {
        using (ESSDataContext ess_context = new ESSDataContext())
        {
            try
            {   
                foreach (var property in objOld.GetType().GetProperties().Where(property => !property.GetGetMethod().GetParameters().Any()))
                {
                   //Check for null values and get hold of oldValue and newValue

                        var sqlResult = ess_context.InsertAuditTable(resourceTag, dbObjectName, username, property.Name, oldValue,
                            newValue, auditEvent.StartDate, auditControlTableID.ToString(),
                            auditEvent.Environment.CallingMethodName);

                }
            }

        }
    }

I've tried using dynamic, but then I don't get the properties correctly.

Igavshne
  • 699
  • 7
  • 33
  • If you have access to `SimpleRequest`, `LeaveRequest`, `Incident`, etc you could make them extend a class w/o any functionality and use that class as your generic type in methods. Might not be a good manner way of handling your problem but it works as far as I have used it with Streams. Oh and you can replace `.Any()` with `.ToList().ForEach(property => { ... })` – JieBaef Sep 10 '19 at 12:08
  • Where are you calling `InsertTargetObjectFields`? is that a custom action or a custom data provider? – thepirat000 Sep 10 '19 at 22:26
  • @thepirat000, the first batch of code is in the overriden `InsertEvent` of my custom `AuditDataProvider`. `InsertTargetObjectFields` is a separate method in the same custom class that extends `AuditDataProvider`. – Igavshne Sep 11 '19 at 09:33
  • @JieBäf, guess I could make them all extend a class... but it feels a bit synthetic. Thanks for your comment though. I'll think about implementing it... – Igavshne Sep 11 '19 at 09:38

0 Answers0