Quantcast
Channel: eXpandFramework RSS
Viewing all articles
Browse latest Browse all 861

BLOG by Robert Anderson: Better handling of Decimals in the XAF audit trail

$
0
0

The following screenshot shows the detail view of an object change from the DevExpress XAF Audit Trail. The DecimalValue property was changed from 123.45 to 543.22.

Why is the OldValue property is displayed with two trailing zeros? The corresponding property is defined as follows:

123456789101112131415161718192021222324252627282930313233343536
[DefaultClassOptions]publicclassMyClass:XPObject{publicMyClass(Sessionsession):base(session){}//...privatedecimal_DecimalValue;    [ModelDefault("DisplayFormat", "{0:n2}")]publicdecimalDecimalValue{get{return_DecimalValue;}set{SetPropertyValue("DecimalValue",ref_DecimalValue,value);}}privateXPCollection<AuditDataItemPersistent>_ChangeHistory;publicXPCollection<AuditDataItemPersistent>ChangeHistory{get{if(_ChangeHistory==null){_ChangeHistory=AuditedObjectWeakReference.GetAuditTrail(Session,this);}return_ChangeHistory;}}}

Explanation and fix

A C# decimal is a type which represents a number’s value and its precision. It actually stores the number of trailing zeros along with the value. For the NewValue, it has stored the decimal value as the user entered it - with no trailing zeros. Howevever, for the OldValue, it has retrieved the value from the database and used the SQL column definition to determine the precision.

The default SQL column type that XPO column type for properties of type decimal is the money type (see the MSDN documentation) which stores 4 decimal places of precision. If we override this with, say, a DECIMAL(28, 13), the audit trail would show 13 decimal places of precision.

From the user’s perspective, this looks a little confusing, so let’s fix it.

During the initialization of your application (in Application_Start for a web application), add an event to the AuditTrailService as follows.

AuditTrailConfig.Initialize();

and then declare the AuditTrailConfig helper class as follows:

123456789101112131415161718192021222324
publicstaticclassAuditTrailConfig{publicstaticvoidInitialize(){AuditTrailService.Instance.SaveAuditTrailData+=Instance_SaveAuditTrailData;}staticvoidInstance_SaveAuditTrailData(objectsender,SaveAuditTrailDataEventArgse){NormalizeOldValuesDecimalPrecision(e);}privatestaticvoidNormalizeOldValuesDecimalPrecision(SaveAuditTrailDataEventArgse){vardecimalAuditTrailDataItems=e.AuditTrailDataItems.Where(i=>i.OldValueisdecimal);foreach(AuditDataItemauditTrailItemindecimalAuditTrailDataItems){// remove any trailing zeros from OldValueauditTrailItem.OldValue=((decimal)auditTrailItem.OldValue).Normalize();}}}

The Normalize() method is an extension method. See the trick in my last post for more information.

1234567
publicstaticclassDecimalExtensions{publicstaticdecimalNormalize(thisdecimalvalue){returnvalue/1.000000000000000000000000000000000m;}}

And then the same change would be logged as follows.


Viewing all articles
Browse latest Browse all 861

Trending Articles