2012-03-04 54 views
1

我目前正在为上传的文件验证创建一些自定义属性。我可以在jQuery验证中访问HttpPostedFileBase的属性吗?

其中之一是一个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有粗略的了解,所以我不知道这是否可能。如果浏览器支持File API

+1

没有它不是,JavaScript是有限的浏览器,并有文件和操作系统的访问限制。 – Lloyd 2012-03-04 04:53:18

回答

3

可以这样做。查询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" }) 
+0

非常酷!谢谢你。那么我至少可以在某些浏览器上支持客户端验证。 – 2012-03-04 18:13:08

相关问题