我正在使用Audit.Net (这是一个很好的实用程序)开始审计一个在设计时没有考虑到审计的系统。在这种情况下,Audit.Net是救命稻草。
我假设有人一定有过类似的情况,我问这个问题是因为我有一种感觉,我走的不是最好的路线。
有不同类型的对象需要审计,但是数据库中已经有一个固定的表(来自系统的另一个部分),审计的数据必须放入其中。
目前,我将通过MVC / Web API控制器传递的对象设置为AuditEvent的目标(使用Audit.MVC版本14.2.1)。
this.GetCurrentAuditScope().SetTargetGetter(() => leaveRequest);我已经扩展了AuditDataProvider,并且需要将目标对象(在本例中为LeaveRequest)的每个属性添加到一个表中。因此,在我的SQLAuditDataProvider中,我获得了LeaveRequest的新值,遍历了它的属性,并将每个非空值写入数据库。带有LeaveRequest的oldvalue并不重要。下面是一个示例:
if (auditEvent.Target.Type == "LeaveRequest")
{
LeaveRequest leaveReq = JsonConvert.DeserializeObject<LeaveRequest>(auditEvent.Target.SerializedNew.ToString());
foreach (var property in leaveReq.GetType().GetProperties().Where(property => !property.GetGetMethod().GetParameters().Any()))
{
if (property.GetValue(leaveReq) != null)
{
var sqlResult = context.sp_ESS_InsertResourceAudit(leaveReq.ResourceTag, dbObjectName, username, property.Name, oldValue,property.GetValue(leaveReq).ToString(), auditEvent.StartDate, auditControlTableID.ToString(),auditEvent.Environment.CallingMethodName);
}
}
}但是,当然,这只适用于LeaveRequest。因此出现了任何其他被设置为AuditEvent的目标的对象,我遇到了一个问题。我如何使上面的代码泛型,以便它可以处理任何对象(甚至是int?)
我也考虑过使用Action参数,但是每个对象都需要充实它的ToString (这可能需要大量的手动工作加上字符串操作才能获得属性),而且感觉并不好和整洁。
所以我不知道这个问题是不是一个简单的泛型问题,而不是一个目标问题,但我认为Audit.Net上下文很重要,也许将每种情况下的对象设置为Audit.Net都不是一个好主意。我很想知道其他人如何使用Audit.Net来审计需要相同输出方式的不同类型的对象。
发布于 2019-05-09 01:42:53
如果您不关心“旧”值,请不要使用Target对象,而是使用Custom Field,这样就可以避免不必要的序列化/反序列化。
this.GetCurrentAuditScope().SetCustomField("LeaveRequest", leaveRequest);所以在你的数据提供者上:
if (auditEvent.CustomFields.ContainsKey("LeaveRequest"))
{
var leaveReq = auditEvent.CustomFields["LeaveRequest"] as LeaveRequest;
InsertLeaveRequest(leaveReq);
}
if (auditEvent.CustomFields.ContainsKey("AnotherField"))
{
var another = auditEvent.CustomFields["AnotherField"] as AnotherType;
InsertAnotherType(another);
}
...对于只有三种类型的对象,你可能不需要有一个通用的解决方案,这意味着更多的测试,等等。
https://stackoverflow.com/questions/56038323
复制相似问题