AttributeAuditDetail Class

Definition

Contains the details of changes to entity attributes.

public ref class AttributeAuditDetail sealed : Microsoft::Crm::Sdk::Messages::AuditDetail
[System.Runtime.Serialization.DataContract(Namespace="http://schemas.microsoft.com/crm/2011/Contracts")]
public sealed class AttributeAuditDetail : Microsoft.Crm.Sdk.Messages.AuditDetail
[<System.Runtime.Serialization.DataContract(Namespace="http://schemas.microsoft.com/crm/2011/Contracts")>]
type AttributeAuditDetail = class
    inherit AuditDetail
Public NotInheritable Class AttributeAuditDetail
Inherits AuditDetail
Inheritance
AttributeAuditDetail
Attributes

Examples

The DisplayAuditDetail static method outputs different details to the console depending on the type of audit detail.

/// <summary>
/// Displays properties of the different classes derived from AuditDetail
/// </summary>
/// <param name="auditDetail">The instance of a type derived from AuditDetail</param>
static void DisplayAuditDetail(AuditDetail auditDetail)
{
      switch (auditDetail)
      {
         case AttributeAuditDetail aad:

            Entity oldRecord = aad.OldValue;
            Entity newRecord = aad.NewValue;
            List<string> oldKeys = new List<string>();

            //Look for changed or deleted values that are included in the OldValue collection
            oldRecord.Attributes.Keys.ToList().ForEach(k =>
            {
                  if (oldRecord.FormattedValues.Keys.Contains(k))
                  {
                     if (newRecord.FormattedValues.Contains(k))
                     {
                        Console.WriteLine(
                              $"\tChange:{k}:{oldRecord.FormattedValues[k]} => " +
                              $"{newRecord.FormattedValues[k]}");
                     }
                     else
                     {

                        Console.WriteLine($"\tDeleted:{k}:" +
                              $"{oldRecord.FormattedValues[k]}");
                     }
                  }
                  else
                  {
                     if (newRecord.Attributes.Keys.Contains(k))
                     {

                        Console.WriteLine($"\tChange:{k}:{oldRecord[k]} => " +
                              $"{newRecord[k]}");
                     }
                     else
                     {
                        Console.WriteLine($"\tDeleted:{k}:{oldRecord[k]}");
                     }
                  }

                  oldKeys.Add(k); //Add to list so we don't check again
            });

            //Look for New values that are only in the NewValues collection
            newRecord.Attributes.Keys.ToList().ForEach(k =>
            {
                  if (!oldKeys.Contains(k))//Exclude any keys for changed or deleted values
                  {
                     if (newRecord.FormattedValues.Keys.Contains(k))
                     {
                        Console.WriteLine($"\tNew Value:{k} => " +
                              $"{newRecord.FormattedValues[k]}");
                     }
                     else
                     {
                        Console.WriteLine($"\tNew Value:{k}:{newRecord[k]}");
                     }
                  }
            });
            break;

         case ShareAuditDetail sad:
            Console.WriteLine($"\tUser: {sad.Principal.Name}");
            Console.WriteLine($"\tOld Privileges: {sad.OldPrivileges}");
            Console.WriteLine($"\tNew Privileges: {sad.NewPrivileges}");
            break;

         //Applies to operations on N:N relationships
         case RelationshipAuditDetail rad:
            Console.WriteLine($"\tRelationship Name :{rad.RelationshipName }");
            Console.WriteLine($"\tRecords:");
            rad.TargetRecords.ToList().ForEach(y =>
            {
                  Console.WriteLine($"\tTarget Record :{y.Name}");
            });
            break;

         //Only applies to role record
         case RolePrivilegeAuditDetail rpad:

            List<string> newRolePrivileges = new List<string>();
            rpad.NewRolePrivileges.ToList().ForEach(y =>
            {
                  if (y != null)
                  {
                     newRolePrivileges.Add(
                     $"\t\tPrivilege Id:{y.PrivilegeId} Depth:{y.Depth}\n");
                  }
            });

            List<string> oldRolePrivileges = new List<string>();
            rpad.OldRolePrivileges.ToList().ForEach(y =>
            {
                  if (y != null)
                  {
                     oldRolePrivileges.Add(
                     $"\t\tPrivilege Id:{(y.PrivilegeId)} Depth:{y.Depth}\n");
                  }
            });

            List<string> invalidNewPrivileges = new List<string>();
            rpad.InvalidNewPrivileges.ToList().ForEach(y =>
            {
                  if (y != null)
                  {
                     invalidNewPrivileges.Add(
                     $"\t\tGuid:{y}\n");
                  }
            });

            Console.WriteLine($"\tNew Role Privileges:\n{string.Join(string.Empty, newRolePrivileges.ToArray())}");
            Console.WriteLine($"\tOld Role Privileges:\n{string.Join(string.Empty, oldRolePrivileges.ToArray())}");
            Console.WriteLine($"\tInvalid New Privileges:\n{string.Join(string.Empty, invalidNewPrivileges.ToArray())}"); ;
            break;

         //Only applies for systemuser record
         case UserAccessAuditDetail uaad:
            Console.WriteLine($"\tAccess Time:{uaad.AccessTime}");
            Console.WriteLine($"\tInterval:{uaad.Interval}");
            break;
      }
}

Remarks

Learn to retrieve audit change history

Constructors

AttributeAuditDetail()

Initializes a new instance of the AttributeAuditDetail class.

Properties

AuditRecord

Gets or sets the related Audit record that contains the change details.

(Inherited from AuditDetail)
DeletedAttributes

Gets a list of deleted attributes.

ExtensionData

Gets or sets the structure that contains extra data. Optional.

(Inherited from AuditDetail)
InvalidNewValueAttributes

Gets a collection of attempted attribute changes that are not valid.

LocLabelLanguageCode

Gets or sets the language code for the label.

NewValue

Gets or sets a collection of new values for an entity attribute.

OldValue

Gets or sets a collection of former values for an entity attribute.

Applies to

See also