Checking image mime, size etc in MVC

前端 未结 2 1447
面向向阳花
面向向阳花 2020-12-12 06:11

I have found here a pretty good way of checking whether the file uploaded by the user is a picture or not, how ever I ran into problems when I tried implementing it.

<
2条回答
  •  一生所求
    2020-12-12 06:56

    Apart from the multiple errors in your code as pointed out in Chris Pratts answer, your wanting to perform validation so the correct approach is to use a ValidationAttribute that implements IClientValidatable so that you get both server side and client side validation.

    An example of a attribute that validates the file type is

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class FileTypeAttribute : ValidationAttribute, IClientValidatable
    {
        private const string _DefaultErrorMessage = "Only the following file types are allowed: {0}";
        private IEnumerable _ValidTypes { get; set; }
    
        public FileTypeAttribute(string validTypes)
        {
            _ValidTypes = validTypes.Split(',').Select(s => s.Trim().ToLower());
            ErrorMessage = string.Format(_DefaultErrorMessage, string.Join(" or ", _ValidTypes));
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            HttpPostedFileBase file = value as HttpPostedFileBase;
            if (file != null)
            {
                var isValid = _ValidTypes.Any(e => file.FileName.EndsWith(e));
                if (!isValid)
                {
                    return new ValidationResult(ErrorMessageString);
                }
            }
            return ValidationResult.Success;
        }
    
        public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ValidationType = "filetype",
                ErrorMessage = ErrorMessageString
            };
            rule.ValidationParameters.Add("validtypes", string.Join(",", _ValidTypes));
            yield return rule;
        }
    }
    

    Then add the following script to your view

    $.validator.unobtrusive.adapters.add('filetype', ['validtypes'], function (options) {
        options.rules['filetype'] = { validtypes: options.params.validtypes.split(',') };
        options.messages['filetype'] = options.message;
    });
    
    $.validator.addMethod("filetype", function (value, element, param) {
        if (!value) {
            return true;
        }
        var extension = getFileExtension(value);
        return $.inArray(extension, param.validtypes) !== -1;
    });
    
    function getFileExtension(fileName) {
        if (/[.]/.exec(fileName)) {
            return /[^.]+$/.exec(fileName)[0].toLowerCase();
        }
        return null;
     }
    

    Then use a view model that includes a property for your file and apply the attribute

    public class ProfileVM
    {
        [FileType("jpg, jpeg, gif")] // add allowed types as appropriate
        public HttpPostedFileBase File { get; set; }
    }
    

    And in the view

    @Html.TextBoxFor(m => m.File, new { type = "file" })
    @Html.ValidationMessageFor(m => m.File)
    

    If client side validation is enabled, you will get an error message and the form will not submit. If its disabled, A ModelStateError error will be added by the DefaultModelBinder and ModelState will be invalid and the view can be returned.

提交回复
热议问题