Sunday, October 14, 2018

TryCatcher: A Reusable Try-Catch Wrapper with Logging

Exception logging can be a tricky thing. With so many ways to log an application event, every developer has their own preferences and can change over time. This may not normally be a problem with small-to-medium applications, where it may be easy enough to update whole projects with new ways to log. For large solutions with multiple components, this can become tricky and at worst impractical.

Enforcing a common logging mechanism helps in code reuse in terms of logging exceptions. This can be extended to the exception handling itself, as the Try-Catch pattern tend to be the same in most cases. TryCatcher is a wrapper class to run a snippet of code within a Try-Catch block, and log any errors thrown if any.

Below is a sample function (StaticMethod()) and the regular way of calling it in void Main().

The RunMethod and RunFunction functions each accepts a delegate, and invokes that delegate within an internal Try-Catch. To execute the StaticMethod() call in the context of the TryCatcher Run-functions, pass them as a delegate to the appropriate function.

The RunMethod and RunFunction functions returns a ValueTuple indicating whether the execution was successful (RunSuccessful), the Exception object if it failed (Exception) and the returned value for functions for the case of RunFunction.

If the function succeeded, the RunSuccessful member is true and the Value member contains the return value of the function executed. If the execution failed due to an exception, RunSuccessful is false, and the Exception member contains the Exception object that was caught. Running the function in this context does not cause a runtime error, as the exception is absorbed and returned in Exception member for further optional processing.

Following are additional ways to use TryCatcher.

Extending the functions to support logging of any exceptions encountered while attempting to execute the delegates, version two adds logging functionalities.

If the Logger member is not defined (e.g. is null), then the logging functionality is ignored. If a valid logger that implements ICatchLogger interface is provided, then any exceptions encountered shall be logged as defined by the ICatchLogger implementation.

Given the errorFunction Action that throws and exception, the first RunMethod prior to registering the Logger absorbs the exception but does not trigger the logging functionality. The second RunMethod, after a simple Logger has been registered, displays the error encountered in the console. This ICatchLogger implementation may be extended to log the exception to a file log containing more information regarding the conditions of the exception.

Saturday, July 1, 2017

Introducing the Scissors Validation Framework

You may download the Scissors Validation Framework from GitHub.

Validations is an essential part of interactive software development. We can get away without it, but unexpected things may happen when a user starts entering unexpected data. Having said that, validation is an oft neglected part of the development process. It's rarely an interesting part of writing software, and when developer's fatigue starts to creep in, becomes the least prioritized task. The system works with or without it, so lazy developers see it as an optional component, not an essential one.

To help combat this repetitive task of implementing validations to data entry modules, I've developed this validations framework to automate the configurations required to validate each field. This handles both client-side scripts validation as well as server-side validation. As there are varieties of jQuery-based validation libraries available, the framework has the flexibility to use one's preferred library, or even custom solutions.

The primary goals of this framework are:
  1. to automate some aspects of page validation across an entire project, and
  2. to ensure these validations are uniform, making it easier to make project-wide changes
The framework has similarities to .NET's built-in StringValidatorAttribute and other similar attributes, and in fact I thought I had found an out-of-the-box solution to what I wanted, but alas, this attribute is usable only for custom configuration sections. It could not be used for our own custom codes.

To start, consider a class named Employee, containing basic employee information.

For this class, we define validation rules using the StringValidatorAttribute (and other corresponding attributes) of the validations framework. To apply size validations to the name fields, we define them as follows:

The above definition indicates that the FirstName field should be between 5 to 50 characters in length, inclusive, and is a required field, while the MiddleName field should be between 5 to 20 characters in length, inclusive, but this time is an optional field as the IsRequired property is not set.

All the validator attributes have the same first constructor argument: the FieldLabel. The FieldLabel is the friendly display name when referring to this property during validation operations. For StringValidatorAttribute, the second and third arguments define the minimum and maximum text lengths. There are other optional settings for the various attributes, like the IsRequired, which defines the property as a required input, among others.

Below is the entire Employee class with appropriate validator attributes defined.

This configures the validation rules to be used for each field in the data entry pages of our application.

Of note is IntValidationAttribute, whose minimum/maximum values are overridden internally as needed, depending on the scope of the Int type decorated. For example, if this attribute is decorating an Int16 property but was defined with a maximum value more than the maximum value of an Int16, internally the validator shall override the defined maximum to instead use Int16.MaxValue.

On the web page where we receive input for Employee details, place textboxes for each of the Employee fields. Place a button to trigger the validation on postback. Additionally, we add a Repeater control to display any validation errors found. We use BootStrap framework for the design.

First, let's check the server-side validations. Best practice is to validate on the server no matter how well written our client-side validations are written, as client-side validations is dependent on so many variables. To validate the inputs, we call the function ScissorValidations.Validator.Validate(), which accepts an instance of the Employee class (can be a new or existing instance) and the mapping definition Dictionary<String, Validator.FieldMap>.

The fieldMapping variable defines how the class properties map to the page controls. Each element in the map holds the name of the property, and the FieldMap, which holds the page control as well as it's value to be validated. The Validate() function returns all validation results found, which can be used as a data source for a repeater control, for example. If none are returned, then it means that the inputs passed validation based on the defined rules, and can now be safely saved.

As a shortcut, it is also possible to let the Validate() function auto-assign the validated values directly into the data class instance that was passed. This is to minimize the need to assign and perform any casting needed which were already done internally during the validation process. Note that this only passes any values deemed valid by the validation process. To enable this functionality, set the global setting ScissorValidations.Validator.Settings.CopyValuesOnValidate to true. For ASP.NET, this can be set during the ApplicationStart() event in global.asax as below.

Now for client-side validations. Scissors Validation Framework acknowledges that client-side validations can have many strategies, be it custom Javascript validations or other established frameworks like BootStrap Validations. Due to this, it is normally advisable to implement one's own implementor, which implements the IValidationImplementor interface. For simplicity, let us use a built-in implementor already in the framework named BootstrapValidationImplementor, found in the ScissorValidations.ValidationImplementors namespace. This implementor uses simple validation configurations based on the BootStrap Validation library.

To wire up the page input controls with the required attributes to work with BootStrap Validations, we use the function InitializeClientValidators(), which accepts another fieldMapping variable, but using a slightly different Dictionary definition. Additionally, generic types need to be defined for the data class type containing the validator attributes we need, as well as an implementor class like BootstrapValidationImplementor.

Similar to the fieldMappings on the server-side validation, the client-side requires mapping the data class properties to their corresponding page input control, but is simpler as it only requires the property name and the target control instance.

Shown in the top half is the plain BootStrap-designed row for the FirstName field. This is how a field would typically look like before the client-side validators are added. After the InitializeClientValidators() function has been called and the FirstName field has been found to contain a validator attribute, then the framework uses the provided implementor class to decorate the input tag with the necessary HTML attributes as required by BootStrap Validations library. The bottom half in the snippet above shows the new attributes added to the input tag with the rules for this field's validations.

In case the built-in implementor is not exactly right to your needs, or you are using a totally different client-side validation strategies, you may use your own implementor by implementing the IValidationImplementor interface. The snippet below shows the contents of the BootstrapValidationImplementor class, which you may base your own off of (each function handles the insertion of required attributes depending on their validator types).

And that sets up both client-side and server-side validations on an ASP.NET page.

There will be more validator attributes to be added in the future, as well as a few more implementors. If you like what you see and wish to make some suggestion, do leave a comment. To get the codes, you may download it from GitHub.

Tuesday, August 7, 2012

Grouping Partial Classes in Visual Studio Solution Explorer

Much has already been said on how useful .Net's partial classes can be. But not much on how to organize them well in Visual Studio's Solution Explorer. Given the below web application project:

Figure 1: New Partial Class File Added

The aspx page WebForm1.aspx has the default code-behind file and the designer file. For example, let's add a partial class to WebForm1 to handle validations for the page. By default, this new class file is not grouped with WebForm1.aspx like the others. Wouldn't it make sense to group this new partial class with the existing group?

The extension VSCommands 2010 has a handy command to join the new class into the existing group. It is as simple as selecting the parent class (in this case, the aspx file) and the new partial class (the aspx.validations.cs file), then clicking on Group Items.

Figure 2: Using VSCommands to Group Items

From here, a popup window will appear verifying which one should be the parent of the selected files, as shown below for Visual Studio 2010:

Figure 3: VSCommands Root Item Selector

We'll keep the aspx file as the parent. With this, we now have the following structure in the Solution Explorer:

Figure 4: New Partial Class Added to Group

The new partial class aspx.validations.cs is now a member of the WebForm1 class group! This also works for Windows Forms projects, and Visual Basic projects as well.

It should be noted that this makes sense for partial classes, but we are not limited to partial classes when grouping them in Solution Explorer! We can join any other class into the group if we wanted. Say, if we have a dedicated helper class for WebForm1 and it is not a partial class, we can still add it to the group. And we can select more than two files at the same time to initiate the item grouping. There will just be more files listed in VSCommands' root item selector in figure 3. It is even possible to attach a class to another sub-item in an existing group, creating deeper levels in the solution tree.

We actually don't need VSCommands to take advantage of this. The grouping is configured in the project file, as shown in the below snippet:

Figure 6: Project File Configurations
In figure 5, the new partial class aspx.validations.cs is given a new node value denoting which existing object it should be attached to. The default classes already has this node connected to WebForm1.aspx, so it is grouped by default. VSCommands just makes things easier and safer to do.

Sunday, April 1, 2012

Mixed Data Types in .NET Arrays

The first thing we learn about arrays is that we declare them as an array of a specific type. Consider the following examples:


The data type for the elements of an array variable is explicitly determined during design-time. Any attempt to assign a string in boolArray element will result in a compile error. To be able to have an array with multiple data types for the elements, we can use ArrayLists. But we can use the basic arrays to store different data types in the elements. We simply declare the variable as an array of objects.



Running this as a console application gives us the below output...

System.String
System.Int32
System.Guid

... showing that the elements are indeed stored as the assigned values' types.

Of course, just because this is possible with arrays doesn't mean we should be doing it just because. Declaring variables as objects should be avoided whenever possible. But there is a place for object arrays in the right circumstances.

To quote another blog who described it really well, "...an ArrayList is simply a collection class - one that supports the IList interface - whose internal memory structure is an array. The keyword here, however, is internal. The ArrayList is not an array." [1]

This means that if we know the size of the array ahead of time, we're better off using object arrays than an ArrayList to avoid the overhead of the internal implementations of the IList interface in the latter. Also, since internally it is an array, adding elements into an ArrayList also involves creating a new array with additional elements, and then copying the old array elements into it.

Just a few things worth considering during design.


[1] Array vs ArrayList by Lycangeek

Friday, October 7, 2011

Excavator and Name Dropper Released

Excavator and Name Dropper applications are both released! Excavator makes moving files around easier, and Name Dropper makes renaming them just as easy. Go to their product pages to see more.

Sunday, July 17, 2011

Tas/cker Version 1.0 Released

Tas/cker Task Tracker's initial release is finally out! Go to the Tas/cker download page to get your copy!

Wednesday, April 20, 2011

The Internet Explorer 6 Countdown

Rapid Streams supports the IE6 Countdown! Internet Explorer 6 has been in service for more than 10 years, but in the fast-paced web, 10 years is an incredibly long time! It's now time to leave this outdated browser to the history books and move forward into the future.

Click here to know more about this movement, encouraged by Microsoft themselves!