【问题标题】:Auditing rows added to Azure table storage审核添加到 Azure 表存储的行
【发布时间】:2011-11-20 06:34:16
【问题描述】:

我创建了以下类,我相信它可以为某些需要它的表中的数据行提供一些很好的审计功能。这是我正在使用的课程:

public class AuditableTableServiceEntity : TableServiceEntity  
{

    protected AuditableTableServiceEntity()
        : base()
    {
    }

    protected AuditableTableServiceEntity(string pk, string rk)
        : base(pk, rk) 
    { 
    }
    #region CreatedBy and ModifiedBy

    private string _CreatedBy;
    [DisplayName("Created By")]
    public string CreatedBy
    {
        get { return _CreatedBy; }
        set { _CreatedBy = value; Created = DateTime.Now; }
    }

    [DisplayName("Created")]
    public DateTime? Created { get; set; }

    private string _ModifiedBy;
    [DisplayName("Modified By")]
    public string ModifiedBy
    {
        get { return _ModifiedBy; }
        set { _ModifiedBy = value; Modified = DateTime.Now; }
    }

    [DisplayName("Modified")]
    public DateTime? Modified { get; set; }

    #endregion

}

那里的任何人都可以建议我可能会考虑为这门课进行的任何其他更改。我相信这没问题,但由于我需要在许多课程中实现这一点,我想听听是否有人可以提出任何更改或添加建议。

【问题讨论】:

    标签: c# azure azure-storage azure-table-storage


    【解决方案1】:
    private string _ModifiedBy;
    
    [DisplayName("Modified By")]
    public string ModifiedBy
    {
        get { return _ModifiedBy; }
        set { _ModifiedBy = value; Modified = DateTime.Now; }
    }
    

    会导致栈溢出:在setter中设置属性的值调用setter,setter设置属性的值,调用setter,以此类推。

    你可以在构造函数中设置属性,但是如果一个实例被序列化和反序列化,事情就会中断:当你反序列化它时,公共的无参数构造函数被调用,并且 setter 被调用......它将属性设置为对象被反序列化的日期和时间,而不是存储的值。


    更好的模式可能是为可审计事件创建另一个表。这可能看起来像这样:

    public class Audit
    {
        public string ModifiedBy { get; set; }
        public DateTime DateModified { get; set; }
        public Type ObjectType { get; set; }
        public string Field { get; set; }
        public object OldValue { get; set; }
        public object NewValue { get; set; }
    
        public static void Record(string user, Type objectType, object oldValue, object newValue)
        {
            Audit newEvent = new Audit
            {
                ModifiedBy = user,
                DateModified = DateTime.UtcNow,  // UtcNow avoids timezone issues
                ObjectType = objectType,
                OldValue = oldValue,
                NewValue = newValue
            };
    
            Save(newEvent);  // implement according to your particular storage classes
        }
    }
    

    然后,每当您对要审核的对象进行更改时,请像这样调用Audit.Record()

    public class SomeKindOfAuditableEntity
    {
        private string _importantFieldToTrack;
    
        public string ImportantFieldToTrack
        {
            get { return _importantFieldToTrack; }
            set
            {
                Audit.Record(GetCurrentUser(), this.GetType(), _importantFieldToTrack, value);
                _importantFieldToTrack = value;
            }
        }
    }
    

    通过这种方式,您可以存储发生在表的所有“有趣”属性上的所有更改的日志。这还有其他一些优点:

    • 您会看到每次更改的旧值和新值
    • 审核日志存储在与数据本身不同的位置,从而将关注点分开
    • 您的数据类不需要基类
    • 保留旧更改的审核,以便您可以查看对象更改的整个日志

    主要缺点是您需要为您感兴趣的每个属性向每个设置器添加代码。有一些方法可以通过属性、反射和面向方面的编程来缓解这种情况——例如参见 Spring 的实现:@ 987654321@ -- 实质上,您将为要跟踪的属性创建一个属性。

    另一个缺点是您会为审计日志消耗大量存储空间 - 但您可以有一个后台进程,在您认为合适的时候定期修剪旧条目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多