加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 对象列表上的MVC3自定义不显眼验证器

发布时间:2020-12-16 09:51:24 所属栏目:asp.Net 来源:网络整理
导读:要开始的基本问题:如何在模型中的对象列表上放置一个自定义的,不显眼的验证器?比如,说我的模型允许多个文件上传,因此我有一个文件列表,我希望我的验证器在每个文件上运行? 现在举一个具体的例子.我有一个自定义的,不显眼的验证器,它检查文件扩展名是否在
要开始的基本问题:如何在模型中的对象列表上放置一个自定义的,不显眼的验证器?比如,说我的模型允许多个文件上传,因此我有一个文件列表,我希望我的验证器在每个文件上运行?

现在举一个具体的例子.我有一个自定义的,不显眼的验证器,它检查文件扩展名是否在禁止的扩展名列表中:

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;
    }
}

在我的IsValid中注意我构建它以接受单个文件或文件列表.

在我的模型类中,我可以在单个HttpPostedFileBase上使用它:

[FileExtensionValidator(ErrorMessage = "Invalid Extension")]
public HttpPostedFileBase Upload { get; set; }

然后我在我的视图中附加到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; }

…客户端验证不再运行;只有服务器端工作.这在执行视图源时很明显. <输入>生成的标记缺少它需要运行的所有data-val属性.在进行调试时,永远不会调用GetClientValidationRules.

我错过了什么?

这可能是因为我如何呈现它?我只是为HttpPostedFileBase使用EditorTemplate:

@model System.Web.HttpPostedFileBase
@Html.TextBoxFor(m => m,new { type = "file",size = 60 })

…我的观点呈现如下:

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

任何建议表示赞赏.

解决方法

这就是我想出来的.

我实际上认为问题最终是由于MVC不知道我希望列表上的数据注释应用于其所有成员.我也不应该这样想.

所以我只是在HttpPostedFileBase周围创建了一个“viewmodel”包装器,并将我的验证器放在那里:

public class UploadedFile {
    [FileExtensionValidator(ErrorMessage = "Invalid Extension")]
    public HttpPostedFileBase File { get; set; }
}

然后,在我的实际模型中,我现在只使用这些列表:

public List<UploadedFile> Uploads { get; set; }

…当然没有更多数据注释,因为它们现在处于UploadedFile中.

然后,通过对视图和editortemplate的微小修改来使用它们,现在可以正常工作,客户端和服务器端. (尽管如此,对我来说还是很笨拙.如果有人有更简单的方法,我仍然很乐意听到它.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读