net mvc formulario form asp asp.net-mvc-4

asp.net-mvc-4 - formulario - razor form asp net mvc



¿Cómo validar el tipo de archivo del atributo HttpPostedFileBase en Asp.Net MVC 4? (1)

Debido a que su atributo hereda de un atributo existente, deberá registrarse en global.asax (consulte esta respuesta para ver un ejemplo), sin embargo , no lo haga en su caso. Su código de validación no funciona, y un atributo de tipo de archivo no debe heredarse de RequiredAttribute : debe heredar de ValidationAttribute y, si desea la validación del lado del cliente, también debe implementar IClientValidatable . Sería un atributo para validar los tipos de archivo (tenga en cuenta este código si se trata de una propiedad que es IEnumerable<HttpPostedFileBase> y valida cada archivo de la colección)

[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<string> _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) { IEnumerable<HttpPostedFileBase> files = value as IEnumerable<HttpPostedFileBase>; if (files != null) { foreach(HttpPostedFileBase file in files) { if (file != null && !_ValidTypes.Any(e => file.FileName.EndsWith(e))) { return new ValidationResult(ErrorMessageString); } } } return ValidationResult.Success; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelClientValidationRule { ValidationType = "filetype", ErrorMessage = ErrorMessageString }; rule.ValidationParameters.Add("validtypes", string.Join(",", _ValidTypes)); yield return rule; } }

Se aplicaría a una propiedad como

[FileType("JPG,JPEG,PNG")] public IEnumerable<HttpPostedFileBase> Attachments { get; set; }

y en la vista

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

Los siguientes scripts son necesarios para la validación del lado del cliente (junto con jquery.validate.js y jquery.validate.unobtrusive.js

$.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) { for (var i = 0; i < element.files.length; i++) { var extension = getFileExtension(element.files[i].name); if ($.inArray(extension, param.validtypes) === -1) { return false; } } return true; }); function getFileExtension(fileName) { if (/[.]/.exec(fileName)) { return /[^.]+$/.exec(fileName)[0].toLowerCase(); } return null; }

Tenga en cuenta que su código está intentando validar también el tamaño máximo del archivo que debe ser un atributo de validación separado. Para ver un ejemplo de un atributo de validación que valida el tamaño máximo permitido, consulte este artículo .

Además, recomiendo La guía completa de validación en ASP.NET MVC 3 - Parte 2 como una buena guía para crear atributos de validación personalizados

Estoy intentando validar un tipo de archivo del atributo HttpPostedFileBase para verificar el tipo de archivo, pero no puedo hacer esto porque la validación está pasando. Cómo podría hacer esto ?

molesto

Modelo

public class EmpresaModel{ [Required(ErrorMessage="Choose a file .JPG, .JPEG or .PNG file")] [ValidateFile(ErrorMessage = "Please select a .JPG, .JPEG or .PNG file")] public HttpPostedFileBase imagem { get; set; } }

HTML

<div class="form-group"> <label for="@Html.IdFor(model => model.imagem)" class="cols-sm-2 control-label">Escolha a imagem <img src="~/Imagens/required.png" height="6" width="6"></label> @Html.TextBoxFor(model => Model.imagem, new { Class = "form-control", placeholder = "Informe a imagem", type = "file" }) @Html.ValidationMessageFor(model => Model.imagem) </div>

ValidateFileAttribute

using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Web; //validate file if a valid image public class ValidateFileAttribute : RequiredAttribute{ public override bool IsValid(object value) { bool isValid = false; var file = value as HttpPostedFileBase; if (file == null || file.ContentLength > 1 * 1024 * 1024) { return isValid; } if (IsFileTypeValid(file)) { isValid = true; } return isValid; } private bool IsFileTypeValid(HttpPostedFileBase file) { bool isValid = false; try { using (var img = Image.FromStream(file.InputStream)) { if (IsOneOfValidFormats(img.RawFormat)) { isValid = true; } } } catch { //Image is invalid } return isValid; } private bool IsOneOfValidFormats(ImageFormat rawFormat) { List<ImageFormat> formats = getValidFormats(); foreach (ImageFormat format in formats) { if(rawFormat.Equals(format)) { return true; } } return false; } private List<ImageFormat> getValidFormats() { List<ImageFormat> formats = new List<ImageFormat>(); formats.Add(ImageFormat.Png); formats.Add(ImageFormat.Jpeg); //add types here return formats; } }