DataAnnotation Regular Expression always returns false for file input

asp.net-mvc, asp.net-mvc-4

Solution

Try modifying the code like below.

@Html.ValidationMessageFor(model => model.MyImage)

My Suggestion

Your form should be like below.

@using (Html.BeginForm("Acion", "Conroller", FormMethod.Post, 
                                      new { enctype = "multipart/form-data" }))
{
    <input type="file" name="FileInfo" value="File to Upload" />
    @Html.ValidationMessageFor(I => I.FileInfo);
    <button type="submit" name="Upload" value="Upload" />
}

HttpPostedFileBaseModelBinder

*When you have a single instance of HttpPostedFileBase as an action parameter or a property in model then mapping the file is completely done by the HttpPostedFileBaseModelBinder and no value providers are used in this case. You may think why no value providers are used in this case, it's because the source is single and clear i.e. Request.Files collection.*

Model

public class UploadFileModel
{
    [FileSize(10240)]
    [FileTypes("jpg,jpeg,png")]
    public HttpPostedFileBase FileInfo { get; set; }
}

FileSizeAttribute

public class FileSizeAttribute : ValidationAttribute
{
    private readonly int _maxSize;

    public FileSizeAttribute(int maxSize)
    {
        _maxSize = maxSize;
    }

    public override bool IsValid(object value)
    {
        if (value == null) return true;

        return _maxSize > (value as HttpPostedFileBase).ContentLength;
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format("The file size should not exceed {0}", _maxSize);
    }
}

FileTypesAttribute

public class FileTypesAttribute: ValidationAttribute
{
    private readonly List<string> _types;

    public FileTypesAttribute(string types)
    {
        _types = types.Split(',').ToList();
    }

    public override bool IsValid(object value)
    {
        if (value == null) return true;

        var fileExt = System.IO
                            .Path
                            .GetExtension((value as
                                     HttpPostedFileBase).FileName).Substring(1);
        return _types.Contains(fileExt, StringComparer.OrdinalIgnoreCase);
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format("Invalid file type. Only the following types {0} 
                                    are supported.", String.Join(", ", _types));
    }
}

Controller Action Method

[HttpPost]
public ActionResult Upload(UploadFileModel fileModel)
{     
    if(ModelState.IsValid)
    {

    }

    return View(fileModel);
}

Problem

I've tried so many regular expressions for the `RegularExpression` data annotation to check if the file extension is an image and it always returns false e.g. I've also tried `FileExtension` attribute but it creates an error on the jquery.validation. I'm using ASP.NET MVC 4 Razor ``` [RegularExpression(@"^.*\.(jpg|gif|jpeg|png|bmp)$", ErrorMessage = "Please use an image with an extension of .jpg, .png, .gif, .bmp")] public string MyImage { get; set; } ``` and this is my markup ``` <div class="editor-field"> @Html.TextBoxFor(x => x.DepartmentImage, new { type = "file" }) @Html.ValidationMessage("DepartmentImageError") @Html.ValidationMessageFor(model => model.DepartmentImage) </div> ``` Could someone show me how to make it work?

Original source