Search code examples
asp.net-mvcentity-frameworkvalidationserver-side-validation

Custom Server Side Validation MVC Entity Framework


I'm trying to hook up some server side validation so there is some sort of last line of defense so bad data doesn't get through. One of my fields depends on a boolean value. If the boolean is true then the int value must be 0. If it is false then it has to between 1 and 7. This is what I have so far but it's not working.

[ValidApplicationPrimary(ComplianceProfile= NFlagComplianceProfile)]
[Column("APPLICATION_PRIMARY")]
public int ApplicationPrimary { get; set; }

[Required]
[Column("NFLAG_COMPLIANCE_PROFILE")]
public bool NFlagComplianceProfile { get; set; }

public class ValidApplicationPrimary : ValidationAttribute
    {
        public Boolean ComplianceProfile { get; set; } 

        public override bool IsValid(object value)
        {
            if (ComplianceProfile)//If they have a compliance profile the value of Application Primary should be 0
            {
                if (((Int32)value) == 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else if (((Int32)value) > 0 && ((Int32)value)<=7) //If Application primary is between 1 and 7 then it is true
            {
                return true;
            }
            else //Outside that range its false
                return false;

        }

I keep getting this error

Error   3   An object reference is required for the non-static field, method, or property 'EntityFrameworkTable.NFlagComplianceProfile.get'

Solution

  • You can't reference other properties in that way. If you have .NET 4 or higher you can do something like this:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public sealed class ValidApplicationPrimary : ValidationAttribute
    {
      private const string DefaultErrorMessage = "If {0} is false, {1} must be 1-7.";
    
      public bool ComplianceProfile { get; private set; }
    
      public override string FormatErrorMessage(string name)
      {
        return string.Format(ErrorMessageString, name, ComplianceProfile );
      }
    
      protected override ValidationResult IsValid(object value, 
                            ValidationContext validationContext)
      {
        if (value != null)
        {
          var complianceProfile= validationContext.ObjectInstance.GetType()
                             .GetProperty(ComplianceProfile);
    
          var complianceProfileValue= complianceProfile
                        .GetValue(validationContext.ObjectInstance, null);
    
            if (complianceProfileValue)//If they have a compliance profile the value of Application Primary should be 0
            {
                if (((Int32)value) == 0)
                {
                    return ValidationResult.Success;
                }
                else
                {
                    return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
                }
            }
            else if (((Int32)value) > 0 && ((Int32)value)<=7) //If Application primary is between 1 and 7 then it is true
            {
                return ValidationResult.Success;
            }
            else //Outside that range its false
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    
    
        }
    
        return ValidationResult.Success;
      }        
    }
    

    Usage:

    [ValidApplicationPrimary("ComplianceProfile")]
    [Column("APPLICATION_PRIMARY")]
    public int ApplicationPrimary { get; set; }
    

    This article describes it in detail: http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2