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.
<
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.