Friday, November 6, 2015

ASP.NET MVC - Customizing RequiredAttribute to display required field validation errors in a different format than the default one

Consider a scenario where you want all Required validators of your MVC application to display error messages in a different format than the default one.
As of ASP.NET MVC 5, the default error message format for required field validator is "The <<field display name>> field is required." For example, "The User name field is required." or "The Password field is required."

But instead, you want them to display in a different format, like - "Please enter value in <<field display name>>." Examples - "Please enter value in User name input box", or "Please enter value in Password input box".

One option is to set "ErrorMessage" property of Required data annotation for each and every fields where this validator is used. However, this can solve the purpose, but it will be tedious and importantly, maintenance nightmare to do so.

Perform following steps to customize default error message of Required validators, and apply them across the application.

Step - 1 Create following custom attribute (for instance, "CustomizedRequiredValidatorAdapter") inheriting from RequiredAttributeAdapter:

    public class CustomizedRequiredValidatorAdapter: RequiredAttributeAdapter
    {
        public CustomizedRequiredValidatorAdapter(ModelMetadata metadata,
                                    ControllerContext context,
                                    RequiredAttribute attribute)
            : base(metadata, context, attribute)
        {
            attribute.ErrorMessage = "Please enter value in {0}.";
        }
    }

This requires "System.Web.Mvc", and "System.ComponentModel.DataAnnotations" namespaces

Step - 2 Replace default RequiredAttribute validator by the one created in Step - 1

Add following in the Application_Start event of Global.asax.cs file:

DataAnnotationsModelValidatorProvider.RegisterAdapter(
                typeof(RequiredAttribute),
                typeof(CustomizedRequiredValidatorAdapter));

That's it! This is all you need to do. Now try running your MVC application and see the error messages on required validation failures and you should see the customized messages.

Further, if you have Globalization implemented, you can set attribute.ErrorMessageResourceType, and attribute.ErrorMessageResourceName in the custom attribute (step - 1) to get the string Error message string from resources file.

ASP.NET MVC >> Using enumerations in AuthorizeAttribute to allow the actions to be invoked by multiple roles

Consider a scenario where you need all/ some of the actions of a controller to be invoked by users having specific roles. For example, a "AdminController" which can be accessed only be users having "Admin" or "SuperUser" roles.

Now, its easy to pass multiple roles as a string in Authorize attribute as below:
[Authorize(Roles="Roles,SuperUser")]

However, this is an absolute maintenance nightmare, because if any of the roles are renamed you will need to remember to update at multiple places.

Imagine creating enum as below

    public enum Roles
    {
        User,
        Admin,
        SuperUser
    }

But as the Roles parameter in Authorize attribute is of string type, it wont allow you to pass multiple enum values there.

In order to fix this issue, we need to to create a new attribute inheriting from MVC's AuthorizeAttribute:

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class AuthorizeEnum: AuthorizeAttribute
    {
        public AuthorizeEnum(params object[] roles)
        {
            if (roles.Any(r => r.GetType().BaseType != typeof(Enum)))
                throw new ArgumentException("roles");

            this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r)));
        }
    }

Now, this attribute can be used to decorate the controllers and/ or actions to pass multiple roles as enum values instead of strings.

[AuthorizeEnum(Roles.User, Roles.Admin)]
public partial class AdminController 
{
..........
}

Wednesday, August 26, 2015

CSS Tips and Tricks: Make an image appearing as disabled.

At times, in your HTML pages, you would want user to display images as disabled.
For example, consider a Delete button in an HTML table where for a few rows you cannot allow delete operations (based on some criteria). In such cases, it would be a good (and self-explanatory) to display Delete image as disabled (instead of hiding the same). Following is the CSS for the same:

.disabledImage {
    opacity: 0.4;
    filter: alpha(opacity=30); /* msie */
}

Example usage:

<img src="../content/images/delete.png" title="cannot delete this entry due to dependency" class="disabledImage"/>

Thursday, August 13, 2015

Strategy Design Pattern - Explained with a real world example (C#)

Strategy Pattern is a Behavioral pattern.

In theory, the Strategy Pattern means - 
A family of algorithms, encapsulates each one, and make them interchangeable.
Strategy lets the algorithm vary independently from the clients that use it.

How do we elaborate it? or what can be a practical example of this?

Let us consider, we are creating a basic simulator for the mobile handset. A user (client application) selects a handset, and should be able to function whatever is supported in the handset.




As we all know there can be different types of mobile devices. Old (and cheapest) devices just support Call and SMS functionalities, and there is a range of smart phones/ new handsets which supports cool hardware and features like, rear camera (i.e., main camera), or front camera (i.e., the camera to take your selfie!). There are number of features in the smartphones (much more than camera), but to make the article a bit simple, we will only focus on following four features:
- Phone Call
- SMS
- Front Camera
- Rear Camera

We are taking example of two different handsets:
1. Nokia 5510 - having only basic features (i.e., phone call and SMS)
2. Nokia Lumia 920 - having tons of cool features (but for our case, its only Front Camera and Rear Camera that matters!)
3. Nokia 6600 - having only rear camera (sorry, but there was no facility to take a selfie with this 10 year old handsets!)

In Object-oriented world these three classes are called as "concrete implementations". So in future we should be able to add a number of handset, and so a concrete class for each of them.

Step 1 Identify the behavior(s) which are common across all the clients.
This means, there is a need of an abstract class containing the behavior which is common across all devices. This will be a base class for all the handsets.
Remember, this abstract class is the heart of Strategy pattern. Means, it will contain (and capable to plug-in) everything to create different handsets and attach various behaviors to them. This class is referred to as "Strategy".

    public abstract class Handset
    {
        public abstract string Display();

        public string MakeACall(string destinationNumber)
        {
            return String.Format("Calling {0}", destinationNumber);
        }

        public string SendSms(string destinationNumber)
        {
            return String.Format("Sending SMS to {0}", destinationNumber);
        }
    }

Display() is an abstract method because all different handsets will have their own implementation of how they should appear.

MakeACall() and SendSms() are concrete methods because all devices should make a call or send an SMS in the same manner.

Step 2 Do something for what varies!
In our example, we have Camera features which are varying in different devices. That means, a few handsets supports both front and rear cameras, whereas a few supports only rear camera, and there are those old phones which doesn't have a camera at all.

Lets create an interface which any type of camera can inherit from:

    public interface IPhotographyDevice
    {
        string TakeSnap(string location);

        string RecordVideo(string location);

    }

And, then the two classes implementing this interface, each class for each type of camera (i.e. rear camera, and front camera)

A class implementing the interface for RearCamera:

    public class RearCamera : IPhotographyDevice
    {
        public int megaPixels { get; set; }

        public RearCamera(int supportedMegaPixels)
        {
            megaPixels = supportedMegaPixels;
        }

        public string TakeSnap(string location)
        {
            return String.Format("Taking Photograph on {0} MP main camera", megaPixels.ToString());
        }

        public string RecordVideo(string location)
        {
            return String.Format("Recording Video on {0} MP main camera", megaPixels.ToString());
        }

    }

So you can see that we have encapsulated the photography features in their concrete implementations (i.e., FrontCamera and RearCamera).

Step 3 Integrating the behavior(s) which vary.
The abstract class should now delegate the photography related behavior to IPhotography interface.
For that, we need to inform the Handset class about IPhotography interface, so all the concrete classes of handsets inheriting from Handset class can use photography features,if they need to support them. (i.e., taking photos, and record videos through Front and/ or Rear cameras).

Handset class revisited to add an instance variable
    public abstract class Handset
    {
........
        public IPhotographyDevice photographyDevice;


    }

Step 4 Implement the methods for the new behavior
Handset class revisited to add TakeSnap and RecordVideo methods which calls relevant methods from concrete photography classes, if supported by the handset.
 public abstract class Handset
    {
....
        public string TakeSnap(string location)
        {
            if (photographyDevice != null)
            {
                return photographyDevice.TakeSnap(location);
            }
            else
            {
                return @"Sorry! this phone doesn't support photography";
            }
        }

        public string RecordVideo(string location)
        {
            if (photographyDevice != null)
            {
                return photographyDevice.RecordVideo(location);
            }
            else
            {
                return @"Sorry! this phone doesn't support videography";
            }
        }

    }

Step 5 Setting behavior dynamically
Our application allow users to change the camera run-time. Notice the "Activate Front Camera" and "Activate Rear Camera" buttons in the screenshot.
Here is the beauty of Strategy pattern wherein you can change the behavior dynamically (run-time polymorphism, as they say!)

Handset class revisited to add a setter method (i.e. a method that sets an instance variable - in our case, it is "photographyDevice"

public abstract class Handset
    {
.......
        public void SetPhotographyDevice(IPhotographyDevice newPhotographyDevice)
        {
            photographyDevice = newPhotographyDevice;
        }
........
    }

Step 6 Implement concrete classes from the Strategy
Now we have our Strategy (i.e. Handset abstract class) is ready, its time to create concrete classes.

public class Nokia5510: Handset
    {
        public override string Display()
        {
            return "This is a very basic model from Nokia with no camera whatsoever!!";
        }
    }
This particular device doesn't support any sort of camera, and so we don't need to set the instance of "IPhotography" variable.
when your application will try to execute any photography related methods (i.e. TakeSnap or RecordVideo) then it will say, the phone doesn't support these features)

public class NokiaLumia920 : Handset
    {
        private readonly int rearCameraMPs = 12;
        private readonly int frontCameraMPs = 5;        

        public NokiaLumia920()
        {
            photographyDevice = new MainCamera(mainCameraMPs);
        }

        public void LoadFrontCamera()
        {
            SetPhotographyDevice(new FrontCamera(frontCameraMPs));
        }

        public void LoadRearCamera()
        {
            SetPhotographyDevice(new RearCamera(rearCameraMPs));
        }
        
        public override string Display()
        {
            return "Nokia Lumia 920... A full-featured phone from Nokia";
        }
    } 
This device supports both front and rear cameras, and the client application can switch the cameras at run-time, by calling "LoadFrontCamera" and "LoadRearCamera" methods which internally calls a setter property to change the behavior. That means, we initially attach the behavior (through constructor), and then change it.

public class Nokia6600 : Handset
    {
        private readonly int rearCameraMPs = 12;

        public Nokia6600()
        {
            photographyDevice = new RearCamera(mainCameraMPs);
        }

        public void LoadFrontCamera()
        {
            //Front-camera are not supported in this device
            SetPhotographyDevice(null);
        }

        public void LoadRearCamera()
        {
            SetPhotographyDevice(new RearCamera(mainCameraMPs));
        }

        public override string Display()
        {
            return "Nokia Lumia 6600... A Nokia phone with a lots of features and a high-resolution camera";
        }

    }

This device supports only rear camera, and so when your application tries to attach front camera, the instance is assigned to a null value. A client application can again start the rear camera by invoking "LoadRearCamera".

Step 7 Code the simulator
By now we have the "Strategy" (i.e. our Handset abstract class), interfaces and their concrete implementations, and concrete handset classes are ready. Now its just a matter of instantiate the handset classes (based on the selected handset in drop-down) and invoking methods in various events of simulator.

Call me lazy :) but I am leaving this to the readers to implement this simulator. Feel free to comment in case if you face any difficulties.

Summary
To summarize and conclude, we have used "Strategy design pattern" in our Mobile Handset simulator application, and following are the benefits:
- Behaviors can be added run-time
- Behaviors can be switched run-time
- Any new implementation of a behavior will not require any change in the "Strategy" class.
- There is a single class (called as Strategy) that contains everything which is required by the clients. (abstract methods, concrete methods, instance variables of Interface type for the behavior and setter methods to change the behavior at run-time)
- If there is a need to supporting any new device in the simulator, and if that device has possible features within call, sms, and camera, then its just a matter of adding a new concrete class for the handset as we have done.
- If the new handsets are supporting a different type of camera (may be, a "spy camera"), then you will just need to create a new concrete type from "IPhotographyDevice", and you should be able to use the "Spy camera" in your simulator straight-away. And similarly, can switch between - front, rear and spy cameras similar to what we did in our example. 
- if the new handsets are supporting some new behaviors, then a new interface for the behavior will need to be added, and so its concrete application (as per step 2). After that the "Strategy" class will need to be integrate that behavior (steps - 3,4,5). And phew, you are ready to use this new behavior.


Hope this article helped you in understanding Strategy pattern. Feel free to ask any questions, or provide feedback!

Wednesday, June 17, 2015

Minify CSS and JS files through PowerShell scripts

The below scripts can be used in scenarios where you need to minify CSS and JavaScript files of your website using PowerShell Scripts. (For example, during Post-build PowerShell scripts in TFS build).

Pre-requisite:
Microsoft Ajax Minifier should be installed on the machine (or TFS build server) where the PowerShell scripts would be executing.
Ajax Minifier can be downloaded from here.

PowerShell scripts to minify CSS files in a directory:

function applyCssMinification($dir)
{
$Minifier = “C:\Program Files (x86)\Microsoft\Microsoft Ajax Minifier\AjaxMin.exe”
get-childitem $dir -recurse -force -include *.css -exclude *.min.css | foreach-object {&$Minifier $_.FullName -out $_.FullName -clobber}

}

PowerShell scripts to minify JavaScript files in a directory:

function applyJsMinification($dir)
{
$Minifier = “C:\Program Files (x86)\Microsoft\Microsoft Ajax Minifier\AjaxMin.exe”
get-childitem $dir -recurse -force -include *.js -exclude *.min.js | foreach-object {&$Minifier $_.FullName -out $_.FullName -clobber}
}

Once defined call these functions by providing CSS and JS directory path as a parameter:

For example,

applyCssMinification "$Env:TF_BUILD_SOURCESDIRECTORY\Website\Content\CSS"


applyJsMinification "$Env:TF_BUILD_SOURCESDIRECTORY\Website\Content\Scripts"

Wednesday, June 3, 2015

PowerShell scripts to apply configuration transformations for App.Config or Web.Config files

By default, Visual Studio provides configuration transformation for Web.config file. As well as, App.Config files can be transformed using a "SlowCheetah" or similar add-ons available in Visual Studio Gallary.

But there may be the cases where the configuration transformation is not supported by project template in Visual Studio, or in case, during TFS build, if you would want to create configuration transformation files for all of the release configurations, and not particular to a single release configuration. 

Through this, the same deployment package created during TFS build can be deployed on different environments.

Following is the PowerShell function I have created to achieve this -

#Apply config transformation
function applyConfigTransformation($src,$xdt,$dst)
{
Add-Type -Path "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.XmlTransform.dll"

try 
{
Write-Host 'applyConfigTransformation - Called'
Write-Host $src
$doc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument
$doc.PreserveWhiteSpace = $true
Write-Host 'applyConfigTransformation - Load Called'
$doc.Load($src)
Write-Host 'applyConfigTransformation - Load completed'

$trn = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt)

if ($trn.Apply($doc))
{
Write-Host 'applyConfigTransformation - $trn.Apply called'
$doc.Save($dst)
Write-Output "Output file: $dst"
Write-Host 'applyConfigTransformation - $trn.Apply completed'
}
else
{
throw "Transformation terminated with status False"
}
}
catch
{
Write-Output $Error[0].Exception

}

Following is how this function can be called -

$src = "C:Projects\MyWebApp\web.config"
$xdt = "C:Projects\MyWebApp\Configs\web.PreProduction.config"
$dst = "C:Projects\MyWebApp\web.PreProduction.config"
applyConfigTransformation $src $xdt $dst

Friday, April 24, 2015

Powershell Scripts to replace "setvar" variable in SQL-CMD script file before running the SQL scripts

Consider having a following SQL file, to run it an SQL-CMD mode:

C:\PowershellTest\CreateDatabase.sql

:setvar ImagesLocation 'C:\ImagesStore\'
........
Update ImagesStore
SET ImagesLocation = '$(ImagesLocation)'
.......


Now, when you run this sql-cmd scripts file during the deployments, you would also want to change the value of ImagesLocation variable, as the location may vary for different environment.

This can be achieved through using regular expressions in Powershell scripts.
In order to do that, you can create a following function in your Powershell deployment or pre-deployment scripts:

#function to replace cmdlet variable in SQL-CMD scripts (i.e., the ones assigned by :setvar). For strange reasons, command line variable assignments has lower precendence than the Sqlcmd scripts setvar. 
function replaceCmdletParameterValueInFile( $file, $key, $value ) {
    $content = Get-Content $file
    if ( $content -match ":setvar\s*$key\s*[\',\""][\w\d\.\:\\\-]*[\'\""_]" ) {
        $content -replace ":setvar\s*$key\s*[\',\""][\w\d\.\:\\\-]*[\'\""_]", ":setvar $key $value" |
        Set-Content $file     
    } else {
        Add-Content $file "$key = $value"
    }
}

Call this function in a following manner:

$scriptfile = "C:\PowershellTest\UpdateImagesLocation.sql"
replacePatternMatchingValueInFile $scriptfile"SET @ImagesLocation" "'\\datashare\appImages'"
replaceCmdParameterValueInFile "C:\PowershellTest\CreateDatabase.sql" "ImagesLocation" "'\\datashare\ImagesStore'"



As a result, the variable assignment for ImagesLocation would be changed to a different value in the sql file, and then that file can be used in Invoke-Sqlcmd to run it.