Monday 24 August 2015

.Net Data Annotations : Add composite Primary Key Code First

Following is the way we can add composite primary key for an entity using Data Annotations.

    
        [Key, Column(Order = 0)]
        [Display(Name = "Year")]
        [Range(2015, 2050)]
        public int Year { get; set; }

        [Key, Column(Order = 1)]
        [Range(1, 12)]
        [Display(Name = "Month")]
        public int Month { get; set; } 


Friday 21 August 2015

REST Architecture : Scrammed explanation

If you want to take a glance @ Rest architecture , following is a brief definition with constraints.

Rest is an Architectural design pattern and not a standard or design methodology.

Roy Fielding is the person who defines REST as follows (~70's)
"Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use."

Simply , a web page represent a state and by clicking a hyperlink you can do the state transfer into a different page.

Following are the Architectural Constraints of REST.

  1. Uniform Interface : Each call is Independent
  2. Statelessness : State is never managed in the server. 
  3. Client-Server : Highly decoupled
  4. Cacheable : Each response must define itself as cacheable or not
  5. Layered System : Client is not sure about the direct connection to the server   
  6. Code on Demand : Server can customize the client functionality without re-writing 
HATEOAS is a terminology that goes with REST. following is the acronym. 

"Hypermedia as the Engine of Application State"

Hypermedia  is a generalization of hypertext along with other media types. This also describes that the API is Self-documenting, very dynamic . ie : Allows changes to API without having to rewrite the client. 

Thursday 20 August 2015

Identify DB Entity exceptions

When the app throws an entity exception, it would give a generic details about the error. By using following exception handling block , we would be able to find particular exception in-detail.

    
   catch (DbEntityValidationException Ex)
            {
                foreach (var errors in Ex.EntityValidationErrors)
                {
                    foreach (var validationError in errors.ValidationErrors)
                    {
                        Trace.TraceInformation("Property: {0} Error: {1}",
                                                validationError.PropertyName,
                                                validationError.ErrorMessage);
                    }
                }
            }


Add validation error to MVC Controller and display the error in View

Following code would add error to the model based on some logic in the Controller.
In the Controller
    
   if ((leaveSummary.AnnualTaken + numOfDays) > leaveSummary.Annual)
       ModelState.AddModelError("Leave", "Annual Leave exhausted !");
   else
       leaveSummary.AnnualTaken = leaveSummary.AnnualTaken + numOfDays;

AddModelError is the method we are using to add the new error.
To display this view in the model we need to do following in the cshtml
    
        
@if (!ViewData.ModelState.IsValid) { @ViewData.ModelState["Leave"].Errors[0].ErrorMessage }

Custom compare Validate in the MVC model

We can use data annotations for the model level validations for most scenarios.  There are situations where we need to go beyond than data annotation validations and following is a data comparison example where we need to use extensive validations.

In this example we are using IValidatableObject in our model class in order to implement the date compare validation.

    
   public class LeaveApply : IValidatableObject
    {
        [Key]
        [HiddenInput(DisplayValue = false)]
        public int LeaveKey { get; set; }

        [Display(Name = "Employee")]
        public int EmployeeId { get; set; }

        [ForeignKey("EmployeeId")]
        public Employee Employee { get; set; }
      

        [Display(Name = "Date From")]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime DateFrom  { get; set; }

        [Display(Name = "Date To")]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime DateTo { get; set; }

       

        public IEnumerable< ValidationResult>  Validate(ValidationContext validationContext)
        {
            if (DateTo < DateFrom)
            {
                yield return new ValidationResult("Date To must be greater than Date From");
            }
        }
    }