我目前正在为上传文件验证创建一些自定义属性。
其中一个是FileSizeAttribute
来强制执行某些限制(例如,不能大于x个字节或小于y个字节)。
有什么办法可以访问HttpPostedFileBase的ContentLength
属性吗?我正在阅读file extension validation上的教程,作者展示了一些简单验证文件扩展名的示例代码。
我想扩展到验证文件大小的客户端(除了服务器端),所以我可以在它们上传之前告诉它们,如果它超出了大小限制。
从可用的代码段中,似乎他只能访问文件名:
jQuery.validator.addMethod("fileextensions", function (value, element, param) {
var extension = getFileExtension(value).toLowerCase();
var validExtension = $.inArray(extension, param.fileextensions) !== -1;
return validExtension;
});
我在这里错了还是我错过了什么?我从来没有使用过jQuery,而且我对JavaScript有一个粗略的了解,所以我真的不知道这是否可能。
答案 0 :(得分:3)
如果浏览器支持File API,则可以执行此操作。查询size
属性很简单。
以下是一个例子:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FileExtensionsAttribute : ValidationAttribute, IClientValidatable
{
private List<string> ValidExtensions { get; set; }
public int MaxContentLength { get; set; }
public FileExtensionsAttribute(string fileExtensions)
{
ValidExtensions = fileExtensions.Split('|').ToList();
}
public override bool IsValid(object value)
{
HttpPostedFileBase file = value as HttpPostedFileBase;
if (file != null)
{
var fileName = file.FileName;
var isValidExtension = ValidExtensions.Any(y => fileName.EndsWith(y));
var isValidContentLength = file.ContentLength < MaxContentLength;
return isValidExtension && isValidContentLength;
}
return true;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ValidationType = "file";
rule.ErrorMessage = this.FormatErrorMessage(ErrorMessage);
rule.ValidationParameters["fileextensions"] = string.Join(",", ValidExtensions);
rule.ValidationParameters["maxcontentlength"] = MaxContentLength.ToString();
yield return rule;
}
}
型号:
public class MyViewModel
{
[FileExtensions("txt|doc", MaxContentLength = 200000)]
public HttpPostedFileBase File { get; set; }
}
控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
查看:
@model MyViewModel
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript">
(function ($) {
var getFileExtension = function (fileName) {
var extension = (/[.]/.exec(fileName)) ? /[^.]+$/.exec(fileName) : undefined;
if (extension != undefined) {
return extension[0];
}
return extension;
};
var getFileSize = function (fileElement) {
if (fileElement.files && fileElement.files.length > 0) {
return fileElement.files[0].size;
}
return -1;
};
$.validator.unobtrusive.adapters.add(
'file', ['fileextensions', 'maxcontentlength'], function (options) {
var params = {
fileextensions: options.params.fileextensions.split(','),
maxcontentlength: options.params.maxcontentlength
};
options.rules['file'] = params;
if (options.message) {
options.messages['file'] = options.message;
}
}
);
$.validator.addMethod('file', function (value, element, params) {
var extension = getFileExtension(value);
var validExtension = $.inArray(extension, params.fileextensions) !== -1;
var fileSize = getFileSize(element);
return validExtension && fileSize < parseInt(params.maxcontentlength);
}, '');
})(jQuery);
</script>
@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.LabelFor(x => x.File)
@Html.EditorFor(x => x.File)
@Html.ValidationMessageFor(x => x.File)
<button type="submit">OK</button>
}
编辑模板(~/Views/Shared/EditorTemplates/HttpPostedFileBase
):
@model HttpPostedFileBase
@Html.TextBoxFor(model => model, new { type = "file" })