Thursday, December 29, 2016

Factory Pattern

The Factory Pattern is a Creational pattern that uses a specialized object solely to create other objects. This pattern deals with the instantiation of objects without exposing the instantiation logic. In other words, a Factory is actually a creator of objects which have a common interface. It relies heavily on inheritance as object creation is delegated to subclasses that implement the factory method to create objects.

This creation of other objects happens by calling a factory method either :
  • By defining it in an interface and implement the same in child classes, (OR)
  • Implement it in base class and optionally override the same in derived classes by eliminating the constructor call
Factory pattern tries to address:
  • eliminating significant duplication of code
  • required information not accessible to the composing object
  • may not provide sufficient level of abstraction
  • may otherwise not be part of the composing object's concerns

Advantages: Factory classes are often implemented because they allow the project to follow Interface Segregation and Dependency Inversion SOLID principles more closely. Some of the advantages of using this pattern are as below:

  • It allows you to introduce an Inversion of Control (IoC) container easily
  • It makes your code more testable as you can mock interfaces
  • It gives you a lot more flexibility when it comes time to change the application (i.e. create new implementations without changing the dependent code)

Example for "Defining it in an interface and implement the same in child classes"
//Interface definition of actual object
public interface IEmployee
{
string GetEmployeeStatus(int empId);
}

public class Employee : IEmployee
{
public string GetEmployeeStatus(int empId)
{
return "Employee";
}
}

public class ContractEmployee : IEmployee
{
public string GetEmployeeStatus(int empId)
{
return "Contract Employee";
}
}

public enum EmployeeType
{
Employee,
Contractor
}

/// Implementation of Factory - Used to create objects
public class Factory
{
public IEmployee GetEmployee(EmployeeType empType)
{
switch (empType)
{
case EmployeeType.Employee:
return new Employee();
case PersonType.Contractor:
return new ContractEmployee();
default:
throw new NotSupportedException();
}
}
}
Example for "Implement Factory Method in Base class and optionally override the same in Derived classes"
public interface IProduct
{
string GetName();
string SetPrice(double price);
}

public class Phone : IProduct
{
private double _price;
public string GetName()
{
return "Apple iPhone";
}

public string SetPrice(double price)
{
this._price = price;
return "success";
}
}

/* Almost same as Factory, just an additional exposure to do something with the created method */
public abstract class ProductAbstractFactory
{
protected abstract IProduct DoSomething();

public IProduct GetObject() // Implementation of Factory Method.
{
return this.DoSomething();
}
}

public class PhoneConcreteFactory : ProductAbstractFactory
{
protected override IProduct DoSomething()
{
IProduct product = new Phone();
//Do something with the object after you get the object.
product.SetPrice(20.30);
return product;
}
}
With this I am concluding the illustration. Feel free to share your feedback.

Happy Programming !!!

Saturday, December 24, 2016

S.O.L.I.D Principles

SOLID is an acronym representing principals of Object Oriented Programming and Design.

  • Single Responsibility
  • Open Closed
  • Liskov Substitution
  • Interface Segregation, and
  • Dependency Inversion
The principles of SOLID are guidelines that can be applied while working on an application by providing a framework through which the programmer may refactor the source code until it is both legible and extensible. It is part of an overall strategy of Agile and Adaptive Software Development.

Single Responsibility Principal (SRP) This is the first principle of SOLID principles. As per SRP, there should not be more than one reason for a class to change, or a class should always handle single functionality. If you put more than one functionality in a Class using C#, it introduces coupling between two functionalities and even if you change one functionality there is a chance of braking coupled functionality, which require another round of testing to avoid any surprises in production environment.

Example: Below Employee class is build without implementing the SRP and handling two responsibilities. One is to Insert employee data and, the other is to Generate Reports for provided employee. Here, if any changes are required to made for Report generation, then the employee class functionality may also affect leading testing employee also.

public class Employee
{
public int Employee_Id { get; set; }
public string Employee_Name { get; set; }

// To Insert data into Employee table
public bool InsertIntoEmployeeTable(Employee emp)
{
return true;
}

// To Generate Report of provided employee
public void GenerateReport(int empId)
{
// Report generation with employee data
}
}

As per SRP, one class should handle only one responsibility. To incorporate this principal, we will create another class to handle the Reporting functionality, so that Employee class will handle only one responsibility and any change in report generation functionality will not affect the Employee class.

After implementing Single Responsibility Principal, above implementation will look like below:

public class Employee
{
public int Employee_Id { get; set; }
public string Employee_Name { get; set; }

// To Insert data into Employee table
public bool InsertIntoEmployeeTable(Employee emp)
{
return true;
}
}

public class ReportGeneration
{
// To Generate Report of provided employee
public void GenerateReport(int empId)
{
// Report generation with employee data
}
}

Open Closed Principle This is the second principle from SOLID principles. In object-oriented programming, the open/closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behavior to be extended without modifying its source code.

Example: Below code snippet explains before implementing Open-Closed principal.

public class ReportGeneration
{
public string ReportType { get; set; }
public void GenerateReport(Employee emp)
{
if (ReportType == "CRS")
{
// Report generation with employee data in Crystal Report.
}

if (ReportType == "PDF")
{
// Report generation with employee data in PDF.
}
}
}

In above example, if we want to introduce another report type like SSRS or Excel, then this class needs to be modified with another If condition to handle the new report type(s). According to Open-Closed principal, Any class should be Open for extension but Closed for modification.

After implementing Open Closed principal, above implementation will look like below, and if you want to introduce a new report type, then we just need to inherit the new class from IReportGeneration. So IReportGeneration is open for extension but closed for modification.

public class IReportGeneration
{
public virtual void GenerateReport(Employee emp)
{
// From base
}
}
public class CrystalReportGeneraion : IReportGeneration
{
public override void GenerateReport(Employee emp)
{
// Generate crystal report.
}
}
public class PDFReportGeneraion : IReportGeneration
{
public override void GenerateReport(Employee emp)
{
// Generate PDF report.
}
}

The Liskov Substitution Principle (LSP) is a particular definition of a subtyping relation, called (strong) behavioral subtyping, that was initially introduced by Barbara Liskov in a 1987 conference keynote address entitled Data abstraction and hierarchy

  • if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program In order to follow this principle we need to make sure that the subtypes respect the parent class.

Example: Below code snippet explains before implementing LSP.
public abstract class Employee
{
public virtual string GetProjectDetails(int empId)
{
return "Base Project";
}
public virtual string GetEmployeeDetails(int empId)
{
return "Base Employee";
}
}

public class CasualEmployee : Employee
{
public override string GetProjectDetails(int empId)
{
return "Child Project";
}
// May be for contractual employee we do not need to store the details into database.
public override string GetEmployeeDetails(int empId)
{
return "Child Employee";
}
}

public class ContractualEmployee : Employee
{
public override string GetProjectDetails(int empId)
{
return "Child Project";
}
// May be for contractual employee we do not need to store the details into database.
public override string GetEmployeeDetails(int empId)
{
throw new NotImplementedException();
}
}

In above example, when we try to call ContractualEmployee.GetEmployeeDetails(empId) will return "Not Implemented" exception by violating LSP. The Liskov Substitution Principle implementation leads creating two interfaces to inherit the base differently for Employee and Contractual classes as below:

public interface IEmployee
{
string GetEmployeeDetails(int empId);
}

public interface IProject
{
string GetProjectDetails(int empId);
}

public class CasualEmployee : IEmployee
{
// May be for contractual employee we do not need to store the details into database.
public override string GetEmployeeDetails(int empId)
{
return "Child Employee";
}
}

public class ContractualEmployee : IProject
{
public override string GetProjectDetails(int empId)
{
return "Child Project";
}
}

Interface Segregation Principle (ISP) states that no client should be forced to depend on methods it does not use.

  • ISP splits interfaces which are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them.
  • ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy.

Example: Below code snippet explains before implementing ISP:
public interface IEmployeeDatabase
{
bool AddEmployeeDetails();
bool ShowEmployeeDetails(int empId);
}

When we have above employee interface used for both employee and non-employee classes with above two methods, we are breaking ISP by forcing non-employee class to show their details. After implementing Interface Segregation Principle, showEmployeeDetails() will be moved to another interface's responsibility as below:

public interface IAddOperation
{
bool AddEmployeeDetails();
}

public interface IGetOperation
{
bool ShowEmployeeDetails(int empId);
}

Dependency Inversion principle (DIP) refers to a specific form of decoupling software modules.It states:

  • High-level modules should not depend on low-level modules. Both should depend on abstractions.
  • Abstractions should not depend on details. Details should depend on abstractions.
The Dependency Inversion principle (DIP) helps us to develop loosely couple code by ensuring that high-level modules depend on abstractions rather than concrete implementations of lower-level modules.

Here is an example without implementing DIP:

public class Email
{
public void SendEmail()
{
// code to send mail
}
}
public class Notification
{
private Email _email;
public Notification()
{
_email = new Email();
}
public void PromotionalNotification()
{
_email.SendEmail();
}
}

In the above example, clearly Notification class will work good for the Email notifications. This scenario is tightly coupled as, if we want to introduce another type of notification, the Notification class also needs to be modified. We can follow below steps to make this as loosely coupled, here is how, as first step change the above class to use interface as below:

public interface IMessenger
{
void SendMessage();
}
public class Email : IMessenger
{
public void SendMessage()
{
// code to send email
}
}
public class SMS : IMessenger
{
public void SendMessage()
{
// code to send SMS
}
}
public class Notification
{
private IMessenger _iMessenger;
public Notification()
{
_ iMessenger = new Email();
}
public void DoNotify()
{
_ iMessenger.SendMessage();
}
}

Still Notification class is dependent on Email class. By using Dependency Injection (DI) we can make it completely loosely coupled. There are 3 ways to implement DI as below:

Constructor Injection

public class Notification
{
private IMessenger _iMessenger;
public Notification(Imessenger pMessenger)
{
_ iMessenger = pMessenger;
}
public void DoNotify()
{
_ iMessenger.SendMessage();
}
}
Property Injection
public class Notification
{
private IMessenger _iMessenger;
public Notification()
{
}
public IMessenger MessageService
{
private get;
set { _ iMessenger = value; }
}
public void DoNotify()
{
_ iMessenger.SendMessage();
}
}
Method Injection
public class Notification
{
public void DoNotify(IMessenger pMessenger)
{
pMessenger.SendMessage();
}
}
Now, the Notification class is completely loosely coupled and this is how Dependency Inversion Principle helps us to write loosely coupled code which is highly maintainable and less error prone.

With this I am concluding the illustration. Feel free to share your feedback. Happy Programming !!!

Sunday, December 18, 2016

RequiredIf Dep Field IsNotNull - Conditional Validation Attribute using MVC / Web API

This topic illustrates how to extend ValidationAttribute to enforce customized validation by validating a field depending on dependents field value.

Scenario: Address.Country is required when Address.City value is not NULL.

We can achieve this by following below steps, and the illustration is developed using MVC 5, Web API 2, EF 6 and Mock

As a first step, Create a new class with name "RequiredIfDepFieldIsNotNullValidator" (preferably in a common location of the solution ie. either in Model or a Common project, as applied) and copy below code:
public class RequiredIfDepFieldIsNotNullValidator : ValidationAttribute
{
private readonly string _dependentProperty;
public RequiredIfDepFieldIsNotNullValidator(string dependentProperty)
{
_dependentProperty = dependentProperty;
}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// get a reference to the property this validation depends upon
var field = validationContext.ObjectType.GetProperty(_dependentProperty);

if (field == null)
{
// field not valid - return an error
return new ValidationResult(string.Format(CultureInfo.CurrentCulture, "Unknown property {0}", new[] { _dependentProperty }));
}

// get the value of the dependent property
var otherPropertyValue = field.GetValue(validationContext.ObjectInstance, null);

// trim spaces and convert dependent value to uppercase to support case senstive comparison
if (otherPropertyValue != null && otherPropertyValue is string)
{
otherPropertyValue = (otherPropertyValue as string).Length == 0 ? null : (otherPropertyValue as string).ToUpper();
}

// trim spaces and convert TargetValue to uppercase to support case senstive comparison
if (targetValue != null && targetValue is string)
{
targetValue = (targetValue as string).Length == 0 ? null : (targetValue as string).ToUpper();
}

// compare the value against the target value
if (otherPropertyValue != null && targetValue == null)
{
// validation failed - return an error
return new ValidationResult(string.Format(CultureInfo.CurrentCulture,
                                        FormatErrorMessage(validationContext.DisplayName), new[] { _dependentProperty }));
}
// validation success - return success
return ValidatioResult.Success;
}
}
We need to create or make changes to Model(s) and Controller(s) as below to implement the created custom validation.

POCO / Model: Create / Modify Address class to apply the custom validation on Country property as below to define Country is required when City is not provided.
public class Address {
public int AddressId {get; set; }

public string Line1 { get; set; }

public string Line2 { get; set; }

public string City { get; set; }

public string State { get; set; }

public string Zip { get; set; }

[RequiredIfDepFieldIsNotNullValidator("City", ErrorMessage = "Country is Required")]
public string Country { get; set; }
}
Controller: The controller for Address entity with a POST method will look like below.

Here, before persisting the changes in database, I am forcing process to re-validate Modal State by calling "this.Validate()", which will help the process to identify and throw an error upfront instead of making a call to DB.
public class AddressController : ApiController
{
[ResponseType(typeof(Address))]
public IHttpActionResult PostAddress(Address address)
{
// use below to force validation before doing anything
this.Validate(address);

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Address.Add(address);
db.SaveChanges();

return CreatedAtRoute("DefaultApi", new { id = address.AddressId }, address);
}
}
Testing: Below TestMethods will help testing the post method to check for the expected validation error:

Here, The first test method will represent a case forcing this.Validate() method and second without forcing this.Validate() in controller's POST method.
// Forcing this.Validate() - this case Controller will thow the error
[TestMethod]
public void RequiredCountryWhenCityIsNotNullTest()
{
Address address = new Address { Line1 = "200 E Main St", Line2 = "Apt B", City = "Reston", State = "VA" };
AddressController addressController = new AddressController();
AddressController.Request = new HttpRequestMessage();
AddressController.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();

addressController.PostAddress(address);

Assert.IsFalse(addressController.ModelState.IsValid);
Assert.IsTrue(addressController.ModelState.Count == 1, "Country is Required");
}
// Without forcing this.Validate() - this case DB will throw the error
[TestMethod]
public void RequiredCountryWhenCityIsNotNullTest()
{
Address address = new Address { Line1 = "200 E Main St", Line2 = "Apt B", City = "Reston", State = "VA" };
try
{
AddressController addressController = new AddressController();
AddressController.Request = new HttpRequestMessage();
AddressController.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();

addressController.PostAddress(address);
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Assert.AreEqual("Country is Required", validationError.ErrorMessage);
}
}
}
}
With this I am concluding the illustration. Feel free to share your feedback.

Happy Programming !!!

RequiredIf Dependant Field IsNull - Conditional Validation Attribute using MVC / Web API

This topic illustrates how to extend ValidationAttribute to enforce customized validation by validating a field depending on dependents field value.

Scenario: Address.Country is required when Address.City value is not provided OR NULL.

We can achieve this by following below steps, and the illustration is developed using MVC 5, Web API 2, EF 6 and Mock

As a first step, Create a new class with name "RequiredIfDepFieldIsNullValidator" (preferably in a common location of the solution ie. either in Model or a Common project, as applied) and copy below code:
public class RequiredIfDepFieldIsNullValidator : ValidationAttribute
{
private readonly string _dependentProperty;
public RequiredIfDepFieldIsNullValidator(string dependentProperty)
{
_dependentProperty = dependentProperty;
}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// get a reference to the property this validation depends upon
var field = validationContext.ObjectType.GetProperty(_dependentProperty);

if (field == null)
{
// field not valid - return an error
return new ValidationResult(string.Format(CultureInfo.CurrentCulture, "Unknown property {0}", new[] { _dependentProperty }));
}

// get the value of the dependent property
var otherPropertyValue = field.GetValue(validationContext.ObjectInstance, null);

// trim spaces and convert dependent value to uppercase to support case senstive comparison
if (otherPropertyValue != null && otherPropertyValue is string)
{
otherPropertyValue = (otherPropertyValue as string).Length == 0 ? null : (otherPropertyValue as string).ToUpper();
}

// trim spaces and convert TargetValue to uppercase to support case senstive comparison
if (targetValue != null && targetValue is string)
{
targetValue = (targetValue as string).Length == 0 ? null : (targetValue as string).ToUpper();
}

// compare the value against the target value
if (otherPropertyValue == null && targetValue == null)
{
// validation failed - return an error
return new ValidationResult(string.Format(CultureInfo.CurrentCulture,
                                        FormatErrorMessage(validationContext.DisplayName), new[] { _dependentProperty }));
}
// validation success - return success
return ValidatioResult.Success;
}
}
We need to create or make changes to Model(s) and Controller(s) as below to implement the created custom validation.

POCO / Model: Create / Modify Address class to apply the custom validation on Country property as below to define Country is required when City is not provided.
public class Address {
public int AddressId {get; set; }

public string Line1 { get; set; }

public string Line2 { get; set; }

public string City { get; set; }

public string State { get; set; }

public string Zip { get; set; }

[RequiredIfDepFieldIsNullValidator("City", ErrorMessage = "Country is Required")]
public string Country { get; set; }
}
Controller: The controller for Address entity with a POST method will look like below.

Here, before persisting the changes in database, I am forcing process to re-validate Modal State by calling "this.Validate()", which will help the process to identify and throw an error upfront instead of making a call to DB.
public class AddressController : ApiController
{
[ResponseType(typeof(Address))]
public IHttpActionResult PostAddress(Address address)
{
// use below to force validation before doing anything
this.Validate(address);

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Address.Add(address);
db.SaveChanges();

return CreatedAtRoute("DefaultApi", new { id = address.AddressId }, address);
}
}
Testing: Below TestMethods will help testing the post method to check for the expected validation error:

Here, The first test method will represent a case forcing this.Validate() method and second without forcing this.Validate() in controller's POST method.
// Forcing this.Validate() - this case Controller will thow the error
[TestMethod]
public void RequiredCountryWhenCityIsNullTest()
{
Address address = new Address { Line1 = "200 E Main St", Line2 = "Apt B", State = "VA" };
AddressController addressController = new AddressController();
AddressController.Request = new HttpRequestMessage();
AddressController.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();

addressController.PostAddress(address);

Assert.IsFalse(addressController.ModelState.IsValid);
Assert.IsTrue(addressController.ModelState.Count == 1, "Country is Required");
}
// Without forcing this.Validate() - this case DB will throw the error
[TestMethod]
public void RequiredCountryWhenCityIsNullTest()
{
Address address = new Address { Line1 = "200 E Main St", Line2 = "Apt B", State = "VA" };
try
{
AddressController addressController = new AddressController();
AddressController.Request = new HttpRequestMessage();
AddressController.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();

addressController.PostAddress(address);
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Assert.AreEqual("Country is Required", validationError.ErrorMessage);
}
}
}
}
With this I am concluding the illustration. Feel free to share your feedback.

Happy Programming !!!

Wednesday, December 14, 2016

RequiredIfNot Conditional Validation Attribute using MVC / Web API

This topic illustrates how to extend ValidationAttribute to enforce customized validation of checking a field's value is provided or not depending on other field value.

Scenario: Address.City is required when Address.Action is not "DELETE".

We can achieve this by following below steps, and the illustration is developed using MVC 5, Web API 2, EF 6 and Mock

As a first step, Create a new class with name "RequiredIfNotValidator" (preferably in a common location of the solution ie. either in Model or a Common project, as applied) and copy below code:
public class RequiredIfNotValidator : ValidationAttribute
{
private RequiredAttribute _innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }

public RequiredIfValidator(string dependentProperty, object targetValue)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// get a reference to the property this validation depends upon
var containerType = validationContext.ObjectInstance.GetType();
var field = containerType.GetProperty(this.DependentProperty);

if (field != null)
{
// get the value of the dependent property
object dependentValue = field.GetValue(validationContext.ObjectInstance, null);

// trim spaces and convert dependent value to uppercase to support case senstive comparison
if (dependentValue != null && dependentValue is string)
{
dependentValue = (dependentValue as string).Trim();
dependentValue as string).Length == 0 ? null : (dependentValue as string).ToUpper();
}

// trim spaces and convert TargetValue to uppercase to support case senstive comparison
if (TargetValue != null && TargetValue is string)
{
TargetValue = (TargetValue as string).Trim();
TargetValue = (TargetValue as string).Length == 0 ? null : (TargetValue as string).ToUpper();
}

// compare the value against the target value
if ((dependentValue == null && TargetValue.Equals("") ||
(dependentValue == null && !TargetValue.Equals("") ||
(dependentValue != null && !dependentValue.Equals(this.TargetValue)))))
{
// try validating this field
if (!_innerAttribute.IsValid(value))
     // validation failed - return an error
     return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName });
}
}
// validation success - return success
return ValidatioResult.Success;
}
}
We need to create or make changes to Model(s) and Controller(s) as below to implement the created custom validation.

POCO / Model: Create or Modify Address class to apply the custom validation on City property as below to define City is required when Action is not DELETE.
public class Address {
public int AddressId {get; set; }

public string Line1 { get; set; }

public string Line2 { get; set; }

[RequiredIfNotValidator("Action", "Delete", ErrorMessage = "City is Required")]
public string City { get; set; }

public string State { get; set; }

public string Zip { get; set; }

public string Country { get; set; }

public string Action { get; set; }
}
Controller: The controller for Address entity with a POST method will look like below.

Here, before persisting the changes in database, I am forcing process to re-validate Modal State by calling "this.Validate()", which will help the process to identify and throw an error upfront instead of making a call to DB.
public class AddressController : ApiController
{
[ResponseType(typeof(Address))]
public IHttpActionResult PostAddress(Address address)
{
// use below to force validation before doing anything
this.Validate(address);

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Address.Add(address);
db.SaveChanges();

return CreatedAtRoute("DefaultApi", new { id = address.AddressId }, address);
}
}
Testing: Below TestMethods will help testing the post method to check for the expected validation error:

Here, The first test method will represent a case forcing this.Validate() method and second without forcing this.Validate() in controller's POST method.
// Forcing this.Validate() - this case Controller will thow the error
[TestMethod]
public void RequiredCityWhenActionIsNotDeleteTest()
{
Address address = new Address { Line1 = "200 E Main St", Line2 = "Apt B", State = "VA", Country = "USA", Action = "Update" };
AddressController addressController = new AddressController();
AddressController.Request = new HttpRequestMessage();
AddressController.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();

addressController.PostAddress(address);

Assert.IsFalse(addressController.ModelState.IsValid);
Assert.IsTrue(addressController.ModelState.Count == 1, "City is Required");
}
// Without forcing this.Validate() - this case DB will throw the error
[TestMethod]
public void RequiredCityWhenActionIsNotDeleteTest()
{
Address address = new Address { Line1 = "200 E Main St", Line2 = "Apt B", State = "VA", Country = "USA", Action = "Update" };
try
{
AddressController addressController = new AddressController();
AddressController.Request = new HttpRequestMessage();
AddressController.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();

addressController.PostAddress(address);
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Assert.AreEqual("City is Required", validationError.ErrorMessage);
}
}
}
}
With this I am concluding the illustration. Feel free to share your feedback.

Happy Programming !!!

Friday, December 9, 2016

RequiredIf Conditional Validation Attribute using MVC / Web API

This topic illustrates how to extend ValidationAttribute to enforce customized validation of checking a field's value is provided or not depending on other field value.

Scenario: Address.City is required when Address.Country's value is "USA".

We can achieve this by following below steps, and the illustration is developed using MVC 5, Web API 2, EF 6 and Mock

As a first step, Create a new class with name "RequiredIfValidator" (preferably in a common location of the solution ie. either in Model or a Common project, as applied) and copy below code:
public class RequiredIfValidator : ValidationAttribute
{
private RequiredAttribute _innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }

public RequiredIfValidator(string dependentProperty, object targetValue)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// get a reference to the property this validation depends upon
var containerType = validationContext.ObjectInstance.GetType();
var field = containerType.GetProperty(this.DependentProperty);

if (field != null)
{
// get the value of the dependent property
object dependentValue = field.GetValue(validationContext.ObjectInstance, null);

// trim spaces and convert dependent value to uppercase to support case senstive comparison
if (dependentValue != null && dependentValue is string)
{
dependentValue = (dependentValue as string).Trim();
dependentValue as string).Length == 0 ? null : (dependentValue as string).ToUpper();
}

// trim spaces and convert TargetValue to uppercase to support case senstive comparison
if (TargetValue != null && TargetValue is string)
{
TargetValue = (TargetValue as string).Trim();
TargetValue = (TargetValue as string).Length == 0 ? null : (TargetValue as string).ToUpper();
}

// compare the value against the target value
if ((dependentValue == null && TargetValue.Equals("") ||
(dependentValue == null && !TargetValue.Equals("") ||
(dependentValue != null && dependentValue.Equals(this.TargetValue)))))
{
// try validating this field
if (!_innerAttribute.IsValid(value))
     // validation failed - return an error
     return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName });
}
}
// validation success - return success
return ValidatioResult.Success;
}
}
We need to create or make changes to Model(s) and Controller(s) as below to implement the created custom validation.

POCO / Model: Create or Modify Address class to apply the custom validation on City property as below to define City is required when selected Country is USA.
public class Address {
public int AddressId {get; set; }

public string Line1 { get; set; }

public string Line2 { get; set; }

[RequiredIfValidator("Country", "USA", ErrorMessage = "City is Required")]
public string City { get; set; }

public string State { get; set; }

public string Zip { get; set; }

public IEnumerable Country { get; set; }
}
Controller: The controller for Address entity with a POST method will look like below.

Here, before persisting the changes in database, I am forcing process to re-validate Modal State by calling "this.Validate()", which will help the process to identify and throw an error upfront instead of making a call to DB.
public class AddressController : ApiController
{
[ResponseType(typeof(Address))]
public IHttpActionResult PostAddress(Address address)
{
// use below to force validation before doing anything
this.Validate(address);

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Address.Add(address);
db.SaveChanges();

return CreatedAtRoute("DefaultApi", new { id = address.AddressId }, address);
}
}
Testing: Below TestMethods will help testing the post method to check for the expected validation error:

Here, The first test method will represent a case forcing this.Validate() method and second without forcing this.Validate() in controller's POST method.
// Forcing this.Validate() - this case Controller will thow the error
[TestMethod]
public void RequiredCityWhenCountryIsUSATest()
{
Address address = new Address { Line1 = "200 E Main St", Line2 = "Apt B", State = "VA", Country = "USA" };
AddressController addressController = new AddressController();
AddressController.Request = new HttpRequestMessage();
AddressController.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();

addressController.PostAddress(address);

Assert.IsFalse(addressController.ModelState.IsValid);
Assert.IsTrue(addressController.ModelState.Count == 1, "City is Required");
}
// Without forcing this.Validate() - this case DB will throw the error
[TestMethod]
public void RequiredCityWhenCountryIsUSATest()
{
Address address = new Address { Line1 = "200 E Main St", Line2 = "Apt B", State = "VA", Country = "USA" };
try
{
AddressController addressController = new AddressController();
AddressController.Request = new HttpRequestMessage();
AddressController.Request.Properties["MS_HttpConfiguration"] = new HttpConfiguration();

addressController.PostAddress(address);
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Assert.AreEqual("City is Required", validationError.ErrorMessage);
}
}
}
}
With this I am concluding the illustration. Feel free to share your feedback.

Happy Programming !!!