ian.blair@softstuff

My technical musings

Getting Audit data out of CRM

When retrieving Audit Log information from Dynamics 365 using 

RetrieveAttributeChangeHistoryRequest attributeChangeHistoryRequest =
                            new RetrieveAttributeChangeHistoryRequest {
                                Target = new EntityReference(Contact.EntityLogicalName, contact.Id),
                                AttributeLogicalName = "new_myfield",
                            };

RetrieveAttributeChangeHistoryResponse attributeChangeHistoryResponse =
                            (RetrieveAttributeChangeHistoryResponse) context.Execute(attributeChangeHistoryRequest);

 

The returned data in the AuditDetails collection will contain an action attribute, this will determine the type of operation that took place.

       foreach (var EachEditRecord in attributeChangeHistoryResponse.AuditDetailCollection.AuditDetails)
       {
             AuditDetail attributeDetail = (AuditDetail) EachEditRecord;
             OptionSetValue action = (OptionSetValue) attributeDetail.AuditRecord["action"];
        }

 

A list of actions are below

The date and userid who made the change can be found with

EntityReference userid = (EntityReference) attributeDetail.AuditRecord["userid"];
                            
DateTime? createdon = (DateTime?) attributeDetail.AuditRecord["createdon"];

 

Some of these will contain more information than others and the resulting AuditDetail result will need to be cast as an AtrributeAuditDetail record to find out the old value of the field, and the new value of the field.

var recType = EachEditRecord.GetType();
if (recType == typeof(AttributeAuditDetail)) {
       if (action.Value==2) { //update

       AttributeAuditDetail ar = (AttributeAuditDetail) attributeDetail;
       bool newval = ar.NewValue.Attributes.Contains("new_myfield")
                              ? (bool) ar.NewValue["new_myfield"]
                             : false;


       bool oldval = ar.OldValue.Contains("new_myfield")
                              ? (bool) ar.OldValue["new_myfield"]
                              : false;
     }
}

 The OldValue and NewValue are both entities that will contain the before and after and can be read in the normal way.