.NET Core 2.0自定义文件验证失效,请求排查问题
排查.NET Core 2.0自定义文件验证无效的问题
我仔细梳理了你提交的代码,发现服务器端和客户端验证都存在若干逻辑问题,导致整个验证功能失效。下面逐一拆解问题并给出修正方案:
一、服务器端验证的问题与修复
1. 扩展名匹配未处理大小写
你的IsValid方法直接用file.FileName.EndsWith(e)判断扩展名,若用户上传.PNG这类大写扩展名的文件,会直接绕过验证。需要统一转成小写再做匹配:
protected override ValidationResult IsValid(object value, ValidationContext validationContext) { IFormFile file = value as IFormFile; if (file != null) { // 统一转小写处理扩展名 var fileExtension = Path.GetExtension(file.FileName).TrimStart('.').ToLower(); if (!_ValidTypes.Any(e => e.ToLower() == fileExtension)) { return new ValidationResult(ErrorMessageExtension); } if (file.Length > MaxSize) { return new ValidationResult(ErrorMessageSize); } } return ValidationResult.Success; }
2. 客户端验证参数未传递
你的AddValidation方法没有把允许的文件类型、最大文件大小这些关键参数传递给客户端,导致客户端验证拿不到校验规则。需要补充对应的data属性:
public void AddValidation(ClientModelValidationContext context) { MergeAttribute(context.Attributes, "data-val", "true"); // 传递允许的文件类型给客户端 MergeAttribute(context.Attributes, "data-val-filetypes-validtypes", string.Join(",", _ValidTypes)); MergeAttribute(context.Attributes, "data-val-filetypes", ErrorMessageExtension); // 传递最大文件大小的数值和提示文本 MergeAttribute(context.Attributes, "data-val-maxfilesize", ErrorMessageSize); MergeAttribute(context.Attributes, "data-val-maxfilesize-value", MaxSize.ToString()); }
3. 可选优化:MaxSize改为可配置(非必需)
当前MaxSize是硬编码的1MB,你可以把它改成可配置属性,方便后续调整:
public int MaxSize { get; set; } = 1048576; // 默认1MB // 构造函数支持自定义大小 public FileTypeAttribute(string errorExtension, string errorSize, string vt, int maxSize = 1048576) { ErrorMessageExtension = errorExtension; ErrorMessageSize = errorSize; _ValidTypes = vt.Split(','); MaxSize = maxSize; }
二、客户端JavaScript验证的核心错误
这部分是导致验证完全无效的主要原因,存在多处逻辑偏差:
- 验证方法名与适配器规则名不匹配(错误写为
cannotbered) - 未正确传递
validtypes参数给验证方法 - 文件循环验证时始终只校验第一个文件
- 缺失文件大小的客户端校验逻辑
修正后的客户端代码
// 文件扩展名验证方法 $.validator.addMethod("filetypes", function (value, element, param) { // 遍历所有上传的文件 for (var i = 0; i < element.files.length; i++) { var extension = getFileExtension(element.files[i].name); // 匹配允许的扩展名(统一小写) if ($.inArray(extension, param) === -1) { return false; } } return true; }); // 扩展名验证适配器:关联服务器端传递的参数 $.validator.unobtrusive.adapters.add('filetypes', ['validtypes'], function (options) { options.rules.filetypes = options.params.validtypes.split(',').map(t => t.toLowerCase()); options.messages.filetypes = options.message; }); // 文件大小验证方法 $.validator.addMethod("maxfilesize", function (value, element, param) { for (var i = 0; i < element.files.length; i++) { if (element.files[i].size > param) { return false; } } return true; }); // 文件大小验证适配器 $.validator.unobtrusive.adapters.add('maxfilesize', ['value'], function (options) { options.rules.maxfilesize = parseInt(options.params.value); options.messages.maxfilesize = options.message; }); // 获取文件扩展名的辅助方法 function getFileExtension(fileName) { if (/[.]/.exec(fileName)) { return /[^.]+$/.exec(fileName)[0].toLowerCase(); } return null; }
三、实体类的注意事项
你的实体类中[FileType]属性的参数顺序是正确的,但要注意:如果你的需求是禁止.png格式,当前传入的"jpg,png,gif"是允许png的,需要改成"jpg,gif"才符合你的预期。
最后验证步骤
- 确保视图中脚本引用顺序正确:
jQuery→jQuery Validate→jQuery Unobtrusive Validate - 测试上传不符合要求的文件(超大文件、png文件),检查客户端和服务器端是否都能触发验证提示
内容的提问来源于stack exchange,提问作者sara
相关产品推荐
相关产品推荐

