我正在使用Audit.Net(这是一个非常有用的实用工具)来开始审核未考虑审核目的的系统。在这种情况下,Audit.Net是救生员。
我认为有人肯定也有类似的情况,我问这个问题是因为我感觉自己并没有走上最佳路线。
需要审计的对象类型不同,但是数据库中已经有一个固定的表(来自系统的另一部分),审计后的数据必须进入该表。
当前,我将通过MVC / Web API
控制器传递的对象设置为AuditEvent的目标(使用Audit.MVC版本14.2.1)。
this.GetCurrentAuditScope().SetTargetGetter(() => leaveRequest);
我已经扩展了AuditDataProvider
,并且需要将Target对象的每个属性(在本例中为LeaveRequest)添加到表中。
因此,在我的SQLAuditDataProvider
中,我获得了LeaveRequest的新值,并遍历其属性并将每个非null值写入数据库。带请假请求的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
?)
我还考虑过使用动作参数,但是然后每个对象都需要充实其ToString(这可能需要大量的手动工作以及要获取属性的字符串操作),而且感觉并不好和整洁。
所以我不知道这个问题是否比Audit.Net问题更简单。但是我认为Audit.Net上下文很重要,并且可能在每种情况下都将对象设置为Target而不是一个好主意。 我想知道其他人如何使用Audit.Net来审核需要相同输出方式的不同类型的对象。
答案 0 :(得分:0)
如果您不关心“旧”值,请不要使用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);
}
...
对于仅三种类型的对象,您可能不需要具有暗示更多测试等的通用解决方案。