validationfoolproof-validation

Complex Custom Validation in Foolproof Validation


I have implemented Complex custom Foolproof validation in my application from this link but sadly its not working.My requirement is simple,I have a input file for uploading an image and there should be a validation if the user chooses to upload file other than specified below

            ".jpg",".png",".gif",".jpeg"

Code is

    [Required(ErrorMessage = "Please upload Photo", AllowEmptyStrings = false)]
    [IsValidPhoto(ErrorMessage="Please select files of type .jpg,.png,.gif,.jpeg")]
    public HttpPostedFileBase PhotoUrl { get; set; }

public class IsValidPhotoAttribute : ModelAwareValidationAttribute
{
    //this is needed to register this attribute with foolproof's validator adapter
    static IsValidPhotoAttribute() { Register.Attribute(typeof(IsValidPhotoAttribute)); }

    public override bool IsValid(object value, object container)
    {
        if (value != null)
        {
            string[] AllowedFileExtensions = new string[] { ".jpg", ".gif", ".png", ".jpeg" };
            var file = value as HttpPostedFileBase;


            if (!AllowedFileExtensions.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.'))))
            {
                return false;
            }


        }
        return true;

    }
}

CSHTML is

 @Html.TextBoxFor(m => m.PhotoUrl, new { @class = "form-control imgUpload", 
 @placeholder = "Please upload Photo", @id = "txtPhoto", @type = "file" })  
 @Html.ValidationMessageFor(m => m.PhotoUrl)

Solution

  • You will not be able to get client side validation unless you also create a script to add the rules. It is not necessary to use foolproof and the following method and scripts will give you both server and client side validation

    public class FileAttachmentAttribute : ValidationAttribute, IClientValidatable
    {
      private List<string> _Extensions { get; set; }
      private const string _DefaultErrorMessage = "Only file types with the following extensions are allowed: {0}";
      public FileAttachmentAttribute(string fileExtensions)
      {
        _Extensions = fileExtensions.Split('|').ToList();
        ErrorMessage = _DefaultErrorMessage;
      }
    
      protected override ValidationResult IsValid(object value, ValidationContext validationContext)
      {
        HttpPostedFileBase file = value as HttpPostedFileBase;
        if (file != null)
        {
          var isValid = _Extensions.Any(e => file.FileName.EndsWith(e));
          if (!isValid)
          {
            return new ValidationResult(string.Format(ErrorMessageString, string.Join(", ", _Extensions)));
          }
        }
        return ValidationResult.Success;
      }
    
      public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
      {
        var rule = new ModelClientValidationRule
        {
          ValidationType = "fileattachment",
          ErrorMessage = string.Format(ErrorMessageString, string.Join(", ", _Extensions))
        };
        rule.ValidationParameters.Add("extensions", string.Join(",", _Extensions));
        yield return rule;
      }
    }
    

    Scripts

    $.validator.unobtrusive.adapters.add('fileattachment', ['extensions'], function (options) {
      var params = { fileattachment: options.params.extensions.split(',') };
      options.rules['fileattachment'] = params;
      if (options.message) {
        options.messages['fileattachment'] = options.message;
      }
    });
    
    $.validator.addMethod("fileattachment", function (value, element, param) {
      var extension = getExtension(value);
      return $.inArray(extension, param.fileextensions) !== -1;
    });
    
    function getExtension(fileName) {
      var extension = (/[.]/.exec(fileName)) ? /[^.]+$/.exec(fileName) : undefined;
      if (extension != undefined) {
        return extension[0];
      }
      return extension;
    };
    

    and then use it as

    [FileAttachment("jpg|gif|png|jpeg")]
    public HttpPostedFileBase PhotoUrl { get; set; }