Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc MVC3自定义不引人注目的对象列表验证程序_Asp.net Mvc_Asp.net Mvc 3_Validation_Unobtrusive Validation - Fatal编程技术网

Asp.net mvc MVC3自定义不引人注目的对象列表验证程序

Asp.net mvc MVC3自定义不引人注目的对象列表验证程序,asp.net-mvc,asp.net-mvc-3,validation,unobtrusive-validation,Asp.net Mvc,Asp.net Mvc 3,Validation,Unobtrusive Validation,开始的基本问题是:如何将自定义的、不引人注目的验证器放在模型中对象列表的顶部?比如说,我的模型允许多个文件上传,因此我有一个文件列表,我希望我的验证器在每个文件上运行 现在来看一个具体的例子。我有一个自定义的、不引人注目的验证器,可以检查文件扩展名是否不在禁止扩展名列表中: public class FileExtensionValidatorAttribute : ValidationAttribute, IClientValidatable { protected static s

开始的基本问题是:如何将自定义的、不引人注目的验证器放在模型中对象列表的顶部?比如说,我的模型允许多个文件上传,因此我有一个文件列表,我希望我的验证器在每个文件上运行

现在来看一个具体的例子。我有一个自定义的、不引人注目的验证器,可以检查文件扩展名是否不在禁止扩展名列表中:

public class FileExtensionValidatorAttribute : ValidationAttribute, IClientValidatable {

    protected static string[] PROHIBITED_EXTENSIONS = {
        // ... List of extensions I don't allow.
    };

    public override bool IsValid(object value) {
        if (value is IEnumerable<HttpPostedFileBase>) {
            foreach (var file in (IEnumerable<HttpPostedFileBase>)value) {
                var fileName = file.FileName;
                if (PROHIBITED_EXTENSIONS.Any(x => fileName.EndsWith(x))) return false;
            }
        } else {
            var file = (HttpPostedFileBase)value;
            var fileName = file.FileName;
            if (PROHIBITED_EXTENSIONS.Any(x => fileName.EndsWith(x))) return false;
        }

        return true;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
        var modelClientVlidationRule = new ModelClientValidationRule {
            ErrorMessage = this.ErrorMessageString,
            ValidationType = "fileextension",
        };
        modelClientVlidationRule.ValidationParameters.Add("prohibitedextensions", string.Join("|", PROHIBITED_EXTENSIONS));

        yield return modelClientVlidationRule;
    }
}
然后在我的视图中附加到jquery的验证器:

jQuery.validator.addMethod("fileExtension", function (value, element, param) {
    var extension = "";
    var dotIndex = value.lastIndexOf('.');
    if (dotIndex != -1) extension = value.substring(dotIndex + 1).toLowerCase();

    return $.inArray(extension, param.prohibitedExtensions) === -1;
});

jQuery.validator.unobtrusive.adapters.add('fileextension', ['prohibitedextensions'], function (options) {
    options.rules['fileExtension'] = {
        prohibitedExtensions: options.params.prohibitedextensions.split('|')
    };
    options.messages['fileExtension'] = options.message;
});
这一切都很好,客户端和服务器端……但只在一个HttpPostedFileBase上。问题是我需要为用户提供上传一个或多个文件的能力。如果我将模型更改为:

[FileExtensionValidator(ErrorMessage = "Invalid Extension")]
public List<HttpPostedFileBase> Uploads { get; set; }
…我的观点是这样的:

<p>@Html.EditorFor(m => m.Uploads)</p>
@Html.EditorFor(m=>m.Uploads)


任何建议都将不胜感激。

以下是我的建议

实际上,我认为问题最终是由MVC造成的,因为MVC不知道我希望列表上的数据注释应用于它的所有成员。我想也不应该

因此,我只是在HttpPostedFileBase周围制作了一个“viewmodel”包装器,并将我的验证器放在那里:

public class UploadedFile {
    [FileExtensionValidator(ErrorMessage = "Invalid Extension")]
    public HttpPostedFileBase File { get; set; }
}
然后,在我的实际模型中,我现在只使用以下列表:

public List<UploadedFile> Uploads { get; set; }
公共列表上载{get;set;}
…当然这里没有更多的数据注释,因为它们现在处于上载文件中


然后,对视图和editortemplate稍作修改以使用它们,现在就可以在客户端和服务器端正常工作了。(尽管如此,我还是觉得很笨拙。如果有人有更简单的方法,我还是很高兴听到。)

您的视图是否呈现多个文本框?上载后,值在客户端的存储位置/方式?是。多个文本框呈现ok,并将ok上传到服务器。(服务器端验证确实在这两个服务器上正确运行。)但是,对不起,我不理解你的第二个问题。你能上传几个文件并使用DOM检查器显示呈现的HTML吗?如果你是说在将我上传的内容发布到服务器后,我还没有看到这一点;我确认服务器端验证仅通过调试器工作。如果你的意思是在我附加文件后但在我上传之前检查DOM,是的,我可以。我认为问题在于,在我附加之前,输入标记根本没有“dataval”属性。与所有其他客户机验证字段一样。ie,这是渲染的内容:。奇怪的是,jquery正在向其中添加class=“valid”,尽管我的js代码没有运行。验证程序插件使用字段名关联规则。您可能希望为
资产[*]
命名字段创建自定义规则,或在提交表单时强制进行特定验证。
public class UploadedFile {
    [FileExtensionValidator(ErrorMessage = "Invalid Extension")]
    public HttpPostedFileBase File { get; set; }
}
public List<UploadedFile> Uploads { get; set; }