2012-03-04 52 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

相關問題