Sunday, October 4, 2015

Code Smells: Long Method Refactoring using Resharper

The object programs that live best and longest are those with shorts methods.  Programmers new to objects often feel that no computation ever takes place, that object programs are endless sequences of delegation.

     Since the early days of programming people have realized that the longer a procedure is, the more difficult  it is to understand. Modern OO languages have pretty much eliminated overhead of in-process calls.There is still overhead to the reader of the code because you have to switch context to see what sub procedure does. But the real key to making it easy to understand small method id good naming. If you have a good name for a method you don't need to look at the body.


     A heuristic we follow is that whenever we feel that need to comment something, we write a method instead. Such a method contains the code that was commented but is named after the intention of the code rather than how it does it. This is also the way to refactor "Comments" code smell.

Ninety-nine percentage of the time, all you have to do to shorten a method is Extract Method . Find parts of the method that seem to go nicely together and make a new method.

If you have a method with lots of parameters and temporary variable  the you can follow the approach I mentioned in another article

Refactoring Long Parameter List:

I have already written an article on refactoring long parameter list : . If you've tried that, and you still have too many temps and parameters, its time to get out the heavy artillery Replace Method with Method Object.


Extract Method :

Extract method is one of the most common refactoring I do.  I look at a method that is too long or look at code that needs a comment to understand its purpose. I then  turn that fragment of code into its own method.


  • Create a new method, and name it after the intention of the method ( name it by what it does, not by how it does it)
  • Copy the extracted code from the source method into the new target method.
  • Scan the extracted code for references to any variables that are local in scope to the source  method. These are local variables and parameters to the method.
  • See whether any temporary variables are used only within this extracted code. If s, declare them in the target method as temporary variables.
  • Look to see whether any of these local-scope variables are modified by the extracted code. If one variable is modified, see whether you can treat the extracted code as a query and assign the result to the variable concerned. if this is awkward, or if there is more than one such variable, you can't extract the method as it stands. You may need to use Split Temporary Variable  and try again. You can eliminate temporary variables with Replace Temp with Query.
  • Pass into the target method as parameters local-scope variables that are read from the extracted code.
  • Compile when you have dealt with all the call-scoped variables
  • Replace the extracted code in the source method with a  call to the target method.
  • Compile and test.

Example using Resharper:

      Here is the initial code with we are going to refactor. Things to notice here  PrintOwing function, has some comments to understand what is the purpose of following portion of code. This is Comments Code Smell. These are the places we can apply Extract Method.

Initial code:


  • Example for extracting method without any arguments:

     Using ReSharper Extract Method we can easily move the code in method so that we do not require to comment the code but the important thing is to give proper name of the extracted method so that we do not need to go inside the method to understand the reason of the code. The shortcut for Extract Method in Resharper is Ctrl+Alt + M or (Ctrl R, M)


It will ask to give name of the method. As the method is printing banner so the name of the method could be as


  • Extracting Method for Local Variable

         ReSharper is intelligent enough to understand the local variable used inside code. So it will automatically take local variable as parameter to the extracted method. Here as example, outstanding variable is used for print detail . We can use same Extract Method refactoring from Resharper without any modification.


The outstanding variable is passed as argument inside PrintDetails method automatically.

  • Extract Method and Reassigning a local variable

This refactoring needs to organize the code little so that it can declare local variable inside method and pass the result as return value. outstanding value is generated inside calculate outstanding portion of code. First task will be to take outstanding variable close to calculation.


As the outstanding variable is moved just before calculation. So doing extract method on calculation section Resharper will automatically return the result of the calculation and reassign to a local variable.


  • Final Code after Refactoring

    The code which need to be commented, are moved to methods using Extract Method. This replace long method code into small methods sequence. As because the extracted method names are self explanatory so we do not need to go inside each code to understand what is the purpose of the method.


Output this refactoring changed PrintOwing method into three line of code which do same operation and code need less effort to understand what this PrintOwing is doing.

Friday, September 11, 2015

Code Smells : Long Parameter List refactoring by Replacing Parameter with Method using Resharper

Long list of parameters in a method, though common in procedural code are difficult to understand and likely to be volatile.


public void paintComponent( Graphics gr, Component renderer, Container parent, int x, int y, int width, int height, Boolean shouldValidate)


You might be trying to minimize coupling between objects. Instead of the called object being aware of relationship between classes, you let the caller locate everything; then the method concentrates on what is being asked to do with  the pieces.

Or a programmer generalizes the routine to deal with multiple variations by creating a general algorithm and a lot of control parameters


There have couple of refactoring ways to reduce long parameter

  • Replace Parameter with method
  • Introduce Parameter Object
  • Preserve  Whole Object

1. Replace Parameter with method

use replace parameter with method when you can get the data in one parameter by making  a request of an object you already know about. This object might be a field or it might be another parameter.


  • If necessary, extract the calculation of the parameter into a method
  • Replace references to the parameter in method bodies with references to the method
  • Compile and test after each replacement
  • Use Remove Parameter on the parameters

Following code is an example where we can replace the parameter using method. The discount level can be called inside discountPrice method. It does not need to pass as parameter.


Now I will refactor the above code using Resharper. To begin we can extract a method for calculation of discount level.

In visual studio select the line you want to extract as method using Resharper. After that you can right click as image or can use Control+R, M


Give proper name of the method


After extracting method, code looks like


Now Inline the method inside as parameter using Resharper


The code state


Again do inline for discountPrice parameter


The next window you can select discountLevel


The code will change will be as


You can also  move the Temporary variable basePrice using Extract Method and  Inline refactoring technique.

The final state of code looks like


Resharper is very good tool you can use for refactoring without the fear of breaking code. But it is recommended to compile your code after each refactoring.

This code look much better and organized after removing unnecessary parameters.

In the next article I will continue other refactoring techniques to reduce Long parameter list.

Sunday, August 23, 2015

Why Refactoring is Important Part of Design and Introduction to Code Smells


Up Front Design

In our current understanding of software development we believe that we design and then we code. A good design comes first, and then the code comes second. Over time the code will be modified, and the integrity of the system, its structure according to that design, gradually fades. The code slowly sinks from engineering to hacking.


How about Agile development, Evolutionary Design?

Agile suggests evolutionary design that allows evolution to become  a viable strategy. It also provides new challenges and skills as designers need to learn how to do a simple design, how to use refactoring to keep design clean, and how to use patterns in an evolutionary style. - Martin Fowler.


Why  is Refactoring important in Agile?

With refactoring you find the balance of work changes. You find that design, rather than occurring all up font, occurs continuously during development. You learn from building the system how to improve the design. The resulting interaction leads to a program with a design that stays good as  development continues. Refactoring is part of evolutionary design.


Does Refactoring violate YAGNI?

The point of YAGNI is that you don't add complexity that isn't needed for the current stories. That is part of the practice of simple design. Refactoring is needed to keep the design as simple as you can, so you should refactor whenever you realize you can make things simpler.


So Is Design Dead?

Not by any means, but the nature of design has changed. In Agile design looks for the following skills

  • A constant desire to keep code as clear and simple as possible.
  • Refactoring skills so you can confidently make improvements whenever you see the need.
  • A good knowledge of patterns: not just the solutions but also appreciating when to use then and how to evolve into them.
  • Designing with an eye to future changes., knowing that decisions takes now will have to be changed in the future.
  • Knowing how to communicate the design to the people who need to understand it, using cod, diagrams and above all: conversation.

That's a fearsome selection of skills, but then being  a good designer  has always been tough.


When should we refactor the code?

Should we allocate two weeks every couple of months to refactoring? Refactoring is something you do all the time in little bursts. You don't decide to refactor, you refactor because you want to do something else and improve the design.

The rule of three
  • Refactor when you add function
  • Refactor when you need to fix a bug
  • Refactor as you do a code review.


Bad Smells In Code

By Kent Back and Martin Flowerimages

if it stinks, change it.

- Grandma Beck, discussing child-rearing philosophy

Deciding when to start refactoring, and when to stop, is just an important to refactoring as knowing how to operate the mechanics of a refactoring.


Code smells can be separated into two categories.

  • Code Smells Within Classes
  • Code Smells Between Classes.


Code Smells Within Classes


There's a fine line between comments that illuminate and comments that obscure. Are the comments necessary? Do they explain "why" and not "what"? Can you refactor the code so the comments aren't required? And remember, you're writing comments for people, not machines.

Long Method

All other things being equal, a shorter method is easier to read, easier to understand, and easier to troubleshoot. Refactor long methods into smaller methods if you can.

Long Parameter List

The more parameters a method has, the more complex it is. Limit the number of parameters you need in a given method, or use an object to combine the parameters.

Duplicated code

Duplicated code is the bane of software development. Stamp out duplication whenever possible. You should always be on the lookout for more subtle cases of near-duplication, too.Don't Repeat Yourself!

Conditional Complexity

Watch out for large conditional logic blocks, particularly blocks that tend to grow larger or change significantly over time. Consider alternative object-oriented approaches such as decorator, strategy, or state.

Combinitorial Explosion

You have lots of code that does almost the same thing.. but with tiny variations in data or behavior. This can be difficult to refactor-- perhaps using generics or an interpreter?

Large Class

Large classes, like long methods, are difficult to read, understand, and troubleshoot. Does the class contain too many responsibilities? Can the large class be restructured or broken into smaller classes?

Type Embedded in Name

Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.

Uncommunicative Name

Does the name of the method succinctly describe what that method does? Could you read the method's name to another developer and have them explain to you what it does? If not, rename it or rewrite it.

Inconsistent Names

Pick a set of standard terminology and stick to it throughout your methods. For example, if you have Open(), you should probably have Close().

Dead Code

Ruthlessly delete code that isn't being used. That's why we have source control systems!

Speculative Generality

Write code to solve today's problems, and worry about tomorrow's problems when they actually materialize. Everyone loses in the "what if.." school of design. You (Probably) Aren't Gonna Need It.

Oddball Solution

There should only be one way of solving the same problem in your code. If you find an oddball solution, it could be a case of poorly duplicated code-- or it could be an argument for the adapter model, if you really need multiple solutions to the same problem.

Temporary Field

Watch out for objects that contain a lot of optional or unnecessary fields. If you're passing an object as a parameter to a method, make sure that you're using all of it and not cherry-picking single fields.


Code Smells Between Classes

Alternative Classes with Different Interfaces

If two classes are similar on the inside, but different on the outside, perhaps they can be modified to share a common interface.

Primitive Obsession

Don't use a gaggle of primitive data type variables as a poor man's substitute for a class. If your data type is sufficiently complex, write a class to represent it. 

Data Class

Avoid classes that passively store data. Classes should contain data and methods to operate on that data, too.

Data Clumps

If you always see the same data hanging around together, maybe it belongs together. Consider rolling the related data up into a larger class.

Refused Bequest

If you inherit from a class, but never use any of the inherited functionality, should you really be using inheritance?

Inappropriate Intimacy

Watch out for classes that spend too much time together, or classes that interface in inappropriate ways. Classes should know as little as possible about each other.

Indecent Exposure

Beware of classes that unnecessarily expose their internals. Aggressively refactor classes to minimize their public surface. You should have a compelling reason for every item you make public. If you don't, hide it.

Feature Envy

Methods that make extensive use of another class may belong in another class. Consider moving this method to the class it is so envious of.

Lazy Class

Classes should pull their weight. Every additional class increases the complexity of a project. If you have a class that isn't doing enough to pay for itself, can it be collapsed or combined into another class?

Message Chains

Watch out for long sequences of method calls or temporary variables to get routine data. Intermediaries are dependencies in disguise. 

Middle Man

If a class is delegating all its work, why does it exist? Cut out the middleman. Beware classes that are merely wrappers over other classes or existing functionality in the framework.

Divergent Change

If, over time, you make changes to a class that touch completely different parts of the class, it may contain too much unrelated functionality. Consider isolating the parts that changed in another class.

Shotgun Surgery

If a change in one class requires cascading changes in several related classes, consider refactoring so that the changes are limited to a single class.

Parallel Inheritance Hierarchies

Every time you make a subclass of one class, you must also make a subclass of another. Consider folding the hierarchy into a single class.

Incomplete Library Class

We need a method that's missing from the library, but we're unwilling or unable to change the library to include the method. The method ends up tacked on to some other class. If you can't modify the library, consider isolating the method.

Solution Sprawl

If it takes five classes to do anything useful, you might have solution sprawl. Consider simplifying and consolidating your design.


Smells to Refactoring cheat sheet


Wednesday, May 7, 2014

ATDD (Acceptance Test Driven Development) or BDD using SpecFlow and Fluent Assertions

Specflow is popular framework for acceptance test driven development. The aim of specflow to provide interface where both domain experts and developers can work together. The domain expert can write acceptance test in business readable language and specflow provides easy interface to generate ATDD/BDD test from that. SpecFlow is inspired from the Cucumber in Ruby. To know details of SpecFlow follow this url

Fluent Assertions is a simple ways of writing assertions in a more natural , more readable  and more expressive manner. You can use Fluent Assertions with any unit testing frameworks i. e. NUnit, MSTest, XUnit or Mb-Unit. You just need to add reference to that unit test framework in your project. Fluent Assertions contains huge number of extensions methods even for throwing exceptions.  There have good documentation on supported extension methods here

Preparing Development Environment:

a) Install Nuget packege for SpecFlow with NUnit:
If you want to use SpecFlow with NUnit you can install the following nuget package manager. However, you can also install SpecFlow and Nunit package separately.

b) Install Fluent Assertion : you will also get dll of Fluent Assertions from nuget.

c) Install Visual Studio 2010 features : You can write BDD code with these packages. But, this will not generate NUnit test code. You will need .feature files where domain expert can write acceptance test. Also from .feature file NUnit code will be generated. So you will need to install visual studio extension to add feature files.

Development Steps:

When you will install specflow visual studio extension then you will be able to add feature file in your project.
.feature file provide domain experts to collaborate with acceptance tests in normal and readable language. However, you can also first write your unit test code and after that you can integrate your code with feature definitions. Here is one example of feature file. The acceptance tests are written in natural language with Given.. When.. Then format. Here is an example of adding task in Kanban board. Kanban service responsibility is to add a new task to Kanban board.

But you may not want to write all test cases at a time for this acceptance scenario. In such case you can comment out one of the expected result and you can generate test for this later.

This will help to develop in TDD style development. Where developer want to write code for passing those acceptance test.
Specflow also make it easy to generate step definitions from this feature file. Just right click on the scenario and generate step definitions

When you will generate code from specflow definitions then it will create functions for each steps.

There have no NUnit test attribute then how NUnit can understand these attribute and test? If you open the .feature.cs file then you will see auto generated code for NUnit framework

As we are writing code test assertions using Fluent assertions so it is independent of NUnit attribute. Lets now write code for all these pending functions to pass the scenario tests.

You can use BeforeScenario and AfterScenario function as Setup and CleanUp for unit testing. Also to communicate within scenario and to store the state of variable you can use ScenarioContext.  Which is very important feature for writing test within a scenario. It provides dictionary with key value pair to store records.
Also using fluent assertions you can compare your expected result easy way.

Now suppose a scenario where user will also provide status of task when it will create a ticket.  In this case most of the step definition of this scenario will be same as previous one but only when user will add task then user will also provide status. Do we need to generate all steps again from feature files?
A good feature of SpecFlow that you do not need to write same Given.. steps again. You can directly map the existing definitions with New scenario.
So for whole scenario you will need to add only two step definitions.

Lets also pass this scenario. What if you want to run only one scenario not both?. Then just comment one scenario from the feature file.
After writing and passing the test code also need to be re factored which is must for TDD .

Run Acceptance Tests:

As I mentioned that tested are actually auto generated for NUnit Framework. So using NUnit UI Runner we can check those tests. All my acceptance tests are written using SpecFlow and fluent assertions but as specflow is integrated with NUnit so it will generate dll which we can run through Nunit Runner. As many automated tools already support NUnit Tests results to display so it will be easy to integrate acceptance test results with TeamCity or other continuous integration tools.

If you are using Resharper then you can easily run and debug step definition within Visual Studio. As the Resharper supports NUnit by default so you do not need to install any plugin for that.

Generate Report:

If you used NUnit console before then you would have generated TestResults.xml which can be easily integrated with Automation tools. You will not  need spectflow help to generate this xml file. But if you want to generate report in specflow format then the following command will generate html file.

The output html will look like this :

I have tried TDD approach to pass those acceptance tests which provided me a skeleton for Kanban service. But there will have many features and progressively new scenarios will be added. 
source code :

Thursday, May 30, 2013

Kendo UI MVC: Display Detail/Child records for each Grid row using Detail Templates


Kendo has good feature to display the detail of any row or relevant child records using detail template. The example already exists in Kendo UI demo site.


There have three different ways to display detail template for grid rows.

1. Server detail template:

If you make server binding in main grid using MVC wrapper then Server Detail Template  is very good option to display child records or detail element for each grid row. Here it is very similar to adding a child control inside a grid using DetailTemplate(…) action. It also gives expression to write as razor MVC syntax.

Example :

2. Client Detail Template :

Some cases you need to display grid records on ajax call.  Example of Datasource ajax call is:

   1: .DataSource(dataSource => dataSource
   2:           .Ajax()
   3:           .Read(read => read.Action("Products_Read", "Home"))
   4:        )

In this case Server Detail Template will not work. Because main grid records are loaded by ajax call dynamically. To display detail template for ajax read call you need to use Client Detail Template . 


The problem is that you need to know some kendo client template syntax. Here has example to write client template scripts ( if-else condition, for loop ) using kendo expression

But You can still write MVC wrapper widget and at the end you have to call ToClientTemplate to use it inside client template.


3. Hybrid Solution:

It is a mix solution of client detail template and using server call to render HTML . So I called this hybrid solution. Inside client script you can also make Javascript ajax call.

   1: <script id="client-template" type="text/x-kendo-template">
   2: <div id="placeholder">
   3: <script>
   4: $.get("url",function(data){
   5:  // do somethings
   6: $(document.getElementById("placeholder)).html(data);
   7: });
   8: </script>
   9: </script>


In this example I am making an simple Javascript ajax call to get data from server side ( calling MVC controller action). In server side through Partial View I am getting the html which is rendered in server side. Using this way you are getting full freedom to write code in MVC razor syntax and Kendo MVC wrapper though you are using client template. After getting html from server side the placeholder div is populated with the resultant HTML.

Note: Jquery element select option “$(‘#placeholder’) does not work as # is used also for Kendo syntax. so that I used  document.getElementById.

Sunday, March 24, 2013

Wizard control widget: my first Jquery Widget


We are familiar with ASP.NET Wizard control and that is powerful to create form which need to perform many steps clicking on next and next button.But in Javascript, the problem in writing such widget control is we usually become dependent to HTML controls. Jquery Widget is giving us such power full and object oriented way to create control or plugin which we can easily make it independent on HTML control and more re-usable. It provides object oriented features such as encapsulation, inheritance.Widget also provides constructor and destructor to manage lifetime of plugin.

In MSDN there have a nice article on JQuery Widget Silk Project is real good example of Jquery Widget.

I found some nice wizard control using Jquery those are dependent on HTML controls. Some good articles on Jquery Widget :

both are almost same and I am not here reinventing wheel. I am using the second article code to create wizard plugin so that I can make it more reusable but I can not say that is perfect for any type of requirement.

If you read the second article ( mentioned above) Code  are pretty simple to understand. I am here just trying here to covert it into Jquery widget.

Jquery widget has constructor like _create method which is invoked first time. Here underscore is used to define private scope. So other object can not call _create method.

So in the _create method I have defined how control can be bind to methods and how control would be displayed initially.

To make it independent of particular Form, I have some properties inside Widget options so that we can set ui element or action there. Wizard widget can be called in form as like other widget.

   1: var wizard= $("#WizardForm").Wizard(
   2:       {
   3:           backButtonId: '#back-step',
   4:           nextButtonId: '#next-step',
   5:           finalButtonId: '#next-step',
   6:           confirmAction: ConfirmAction,
   7:           finalAction: FinalAction
   8:       });

  Here back-step, next-step are HTML button ids. and ConfirmAction and FinalAction are methods which is using as callback method.

To set those properties jquery widget provides us to create options object with these properties.

   1: $.widget("system.Wizard", {
   2:         options: {
   3:             backButtonId: '',
   4:             nextButtonId: '',
   5:             finalButtonId: '',
   6:             finalAction: null,
   7:             confirmAction: null
   8:         },
  10:         _create: function () {
  11:             var that = this, name =;
  12:             this.FirstStep = this.element.find(".wizard-step:first");
  13:             this.FirstStep.fadeIn();
  14:             this.CurrentStep = this.FirstStep;
  15:             $(this.options.backButtonId).click(function () { that.moveBack(); })
  16:             $(this.options.nextButtonId).click(function () { that.moveNext(); })
  17:         },

In this code we have exposed some properties so that user can set those properties as defined above and in _create method provided control ids are bind with widget method to make it reusable.

We exposed two method for logic to go next step or in previous step. This code need more improvement to make it more reusable. In the moveNext() method I have called callback method so that we can perform some actions which are dependent on particular UI control

   1: moveNext: function () {
   3:            var $step = this.CurrentStep; // get current step
   5:           //part of code
   7:           if ($"confirm")) { // is it confirmation?
   8:               //invoking callack method
   9:                this.options.confirmAction($step);
  11:            }
  13:            //part of code 
  15:            else { // this is last step, submit form
  16:                this.options.finalAction();
  17:            }
  18:        }     

Here is complete code of Wizard plugin.

Sunday, March 17, 2013

Custom Conditional Validation Depends on Another Property Value using JQuery Unobtrusive feature and ASP.NET MVC


Data Annotation Validation Attribute ( example [Required]) makes easy to provide validation in ASP.NET MVC. Also if Enable unobtrusive validation, we do not need to write any code in JavaScript for client validation. Jquery unobtrusive  validation parse the data attribute in HTML and we do not need to any custom code to validate form.

To enable client side  validation and unobtrusive validation we need to provide settings in web.config or in server side HtmlHelper.


   1: <appSettings>
   2:     <add key="ClientValidationEnabled" value="true" />
   3:     <add key="UnobtrusiveJavaScriptEnabled" value="true" />
   4: </appSettings>


   1: HtmlHelper.ClientValidationEnabled = true;
   2: HtmlHelper.UnobtrusiveJavaScriptEnabled = true;

If  jquery unobtrusive library is referenced in cshtml then there do not need to write any custom code to validate form with the help of data annotation validation attribute.

   1: public class CustomerFormModel : ICustomerCommand
   2:   {
   3:       public int Id { get; set; }
   5:       [Required(AllowEmptyStrings = false, ErrorMessageResourceName = "CustomerNameRequired", ErrorMessageResourceType = typeof(StringTable))]
   6:       [StringLength(200, ErrorMessageResourceName = "CustomerNameLenthValidationError", ErrorMessageResourceType = typeof(StringTable))]
   7:       public string Name { get; set; }
   8: }

When this code will be executed the form can be validated automatically by jquery unobtrusive validation.


When you enable unobtrusive validation ASP.NET MVC add data attribute in HTML  for each data annotation.


In HTML attributes are generated for data annotation in server side and jquery unobtrusive library parsed those attribute for client validation.

But what will happen if validation on any field depends on the value of another field value. You may also want this validation not only client side but also in server side. Usually in such case we write custom validation before submitting form and also do same validation in server side.  We can also do same custom validation using Data annotation and jquery unobtrusive validation without directly referencing client control.

Suppose the requirement is to validate Email field as required only if Name field is not empty. So if Name field is not empty then we do not have to provide Email.

It this case the server side validation would be not difficult. We can create an data annotation attribute which will make decision based on value of Name property.

This is not final code.

   1: namespace SimpleTier.Domain.Validators
   2: {
   3:     using System;
   4:     using System.Collections.Generic;
   5:     using System.Linq;
   6:     using System.Text;
   7:     using System.ComponentModel.DataAnnotations;
   8:     using System.Web.Mvc;
   9:     using SimpleTier.Domain.Properties;
  11:     public class EmailValueValidator : ValidationAttribute
  12:     {
  13:         private string _dependentPropery;
  14:         private bool _isRequired;
  15:         public EmailValueValidator(string dependentpropery, bool isrequired)
  16:             : base()
  17:         {
  18:             _dependentPropery = dependentpropery;
  19:             _isRequired = isrequired;
  20:         }
  22:         protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  23:         {
  24:             if (_isRequired == false) return null;
  25:             System.Reflection.PropertyInfo property = validationContext.ObjectType.GetProperty(_dependentPropery);
  26:             if (property != null)
  27:             {
  28:                 var value1 = property.GetValue(validationContext.ObjectInstance, null) as string;
  29:                 if (string.IsNullOrEmpty(value1) == false && string.IsNullOrEmpty(value as string))
  30:                     return new ValidationResult("Value can not be empty");
  32:                 return null;
  34:             }
  35:             else
  36:                 new ValidationResult(string.Format("Unknown Properties {0}", _dependentPropery));
  38:             return null;
  40:         }
  42:     }
  43: }

In this code a custom validation attribute is created. IsValid() function gets the value of Name field and make decision based on Name value. Attribute on Email property can be defined as:

   1: public class CustomerFormModel : ICustomerCommand
   2:    {
   3:        public int Id { get; set; }
   5:        [Required(AllowEmptyStrings = false, ErrorMessageResourceName = "CustomerNameRequired", ErrorMessageResourceType = typeof(StringTable))]
   6:        [StringLength(200, ErrorMessageResourceName = "CustomerNameLenthValidationError", ErrorMessageResourceType = typeof(StringTable))]
   7:        [TextLineInputValidator]
   8:        public string Name { get; set; }
  10:        //[Required(AllowEmptyStrings = false, ErrorMessageResourceName = "EmailRequired", ErrorMessageResourceType = typeof(StringTable))]
  11:        [EmailValueValidator("Name",true)]
  12:        [StringLength(200, ErrorMessageResourceName = "EmailStringLengthValidationError", ErrorMessageResourceType = typeof(StringTable))]
  13:        public string Email { get; set; }
  14: }

Here Name is the property on which validation depends and also sets another value to determine validation logic is required or not.  But this validation works only on server side and in the HTML code no such validation attribute is created.


To make this validation work also on client side some Html attribute need to be created and make jquery unobtrusive library understand those attribute. To create those html attribute our custom attribute class need to be implemented  by IClientValidatable interface. If class is implemented by IClientValidatable interface,  method name GetClientValidationRules() can be implemented to define the rules that will be generate as html attribute.



We need to define such rule in unobtrusive adapter so that client side validation understand these html attribute. unobtrusive adapter gives option to define method which will work with such rules and defined data attribute.

   1: <script type="text/javascript">
   2:     $.validator.unobtrusive.adapters.add(
   3:         'emailcustomvalidation',['dependentpropery','isrequired'],function(options)
   4:         {
   5:             options.rules["emailcustomvalidation"] =
   6:                 {
   7:                     dependentpropery: options.params.dependentpropery,
   8:                     isrequired: options.params.isrequired
   9:                 };
  10:             options.messages["emailcustomvalidation"] = options.message;
  11:         });
  12:     $.validator.addMethod("emailcustomvalidation", function(value, element, params)
  13:     {
  14:         var parts =".");
  15:         var prefix = "";
  16:         if (parts.length > 1)
  17:             prefix = parts[0] + ".";
  18:         var emailvalue = $('input[name="' + prefix + params.dependentpropery + '"]').val();
  19:         if (!value && !emailvalue)
  20:             return true;
  21:         if (emailvalue && !value)
  22:             return false;
  23:         return true;
  24:     })
  27: </script>

Here same validation is defined as server side code. When the save button will be clicked the form will be be validate and it will call this method. Client side validation provides same validation with error message defined in server side. Such validation can be used for multiple controls as that does not depend on any HTML control.