2016-08-09 60 views
0

我有一個MVC項目,我正在使用jquery不顯眼的驗證純粹由標記單獨。有一件事情是對我錯誤的文件MIME類型的驗證消息。jQuery不顯眼的驗證錯誤消息的文件類型

下面是一些驗證我使用的是普通的文本輸入一個例子:

<input class="form-control valid" data-val="true" data-val-regex="not correct regex message." data-val-regex-pattern="^.{0,440}$" id="field1" name="field1" placeholder="max 440 characters" type="text" value=""> 

輸入已被簡化。但這基本上是我如何使用它,純粹是「數據」屬性。

但是,我不知道的是文件上傳。我已經加入了「附加methods.js」文件和「接受」屬性與相應的消息正確驗證:

<input accept="image/jpeg,image/pjpeg,image/png,image/bmp,image/x-windows-bmp,image/x-ms-bmp" class="dynamicDocumentFileUpload" data-val="true" data-val-required="this is required" id="field2" name="field2" placeholder="file input field" title="upload picture" type="file" value=""> 

如此要求是否按預期運行,如果我嘗試上傳的文件是不正確的MIME類型,驗證將按照預期阻止表單提交。 但是!它只是在「@ Html.ValidationMessageFor」中顯示輸入的名稱。我不知道什麼數據屬性對應於「接受」驗證。

我已經試過這樣:

@Html.ValidationMessageFor(m => Model.Groups[g].Fields[f].File, "wrong file type") 

但該消息是錯誤類型,無論顯示,當然。

+0

有沒有的。您需要創建自己的驗證屬性和關聯的腳本以將方法添加到'jquery.validate'。例如,請參閱[本文](http://blog.2mas.xyz/creating-custom-unobtrusive-file-extension-validation-in-asp-net-mvc-3-and-jquery/)。 –

+0

顯示你的模特類 – anand

+0

沒有模特兒。這就是爲什麼我純粹使用數據註釋。 它是一種自動生成的表單,因此它可以包含X個不同類型的輸入標籤。這就是爲什麼最簡單的驗證方法是使用數據註釋。它實際上就像一個魅力一樣,除了爲文件上傳的「接受」屬性提供消息外。 –

回答

0

在MVC(模型視圖控制器)中開發時避免使用模型並不是一個好主意。正如MVC的含義所說,大多數情況下,在使用IsValid方法將數據保存到數據庫之前,您應該驗證模型。我可以給你的建議是忘記你的工作方式,因爲它不安全。如果不使用模型的isvalid方法,您應該保護您的網站免受XSS腳本攻擊和其他類型的攻擊。模型的主要優點是您可以在保存這些數據之前輕鬆驗證它,並且您可以通過創建自己的驗證屬性來輕鬆解決此類問題,這將在服務器端和客戶端中檢查這些數據。忘記你正在做的事情,並試着瞭解自定義驗證。但是,我可以分享這個代碼,如果您使用的是模型,它將檢查服務器中的文件類型。

 public class FileTypeAttribute : ValidationAttribute 
{ 
    public string thefile{ get; set; } 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     PropertyInfo[] propriétés = validationContext.ObjectType.GetProperties(); 
     PropertyInfo lafichies = propriétés.FirstOrDefault(p => p.Name == lefichier); 

     HttpPostedFileBase valFichierChoisi = thefile.GetValue(validationContext.ObjectInstance, null) as HttpPostedFileBase; 
     byte[] chkBytejpg = { 255, 216, 255, 224 }; 
     byte[] chkBytejpg2 = { 255, 216, 255, 225 }; 

     if (value != null && value.Equals(valFichierChoisi)) 
     {//we check the type for jpeg file 
      //------------------------------------------- 
      if (valFichierChoisi.ContentType.ToLower() != "image/jpg" && 
         valFichierChoisi.ContentType.ToLower() != "image/jpeg" && 
         valFichierChoisi.ContentType.ToLower() != "image/pjpeg") 

      { 
       return new ValidationResult(ErrorMessage); 
      } 


      // Attempt to read the file and check the first bytes 
      //------------------------------------------- 
      try 
      { 
       if (!valFichierChoisi.InputStream.CanRead) 
       { 
        return new ValidationResult(ErrorMessage); 
       } 

       if (valFichierChoisi.ContentLength < ImageMinimumBytes) 
       { 
        return new ValidationResult(ErrorMessage); 
       } 

       byte[] buffer = new byte[valFichierChoisi.ContentLength]; 
       valFichierChoisi.InputStream.Read(buffer, 0, valFichierChoisi.ContentLength); 
       string content = System.Text.Encoding.UTF8.GetString(buffer); 
       if (Regex.IsMatch(content, @"<script|<html|<head|<title|<body|<pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy", 
        RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline)) 
       { 
        return new ValidationResult(ErrorMessage); 
       } 
       //you compare buffer sequence of file and known byte of jpeg in .net 
       if (chkBytejpg.SequenceEqual(buffer.Take(chkBytejpg.Length))) 
       { 
        return ValidationResult.Success; 
       } 

       else if (chkBytejpg2.SequenceEqual(buffer.Take(chkBytejpg2.Length))) 
       { 
        return ValidationResult.Success; 
       } 

      } 
      catch (Exception) 
      { 
       return new ValidationResult(ErrorMessage); 
      } 

      //------------------------------------------- 
      // Try to instantiate new Bitmap, if .NET will throw exception 
      // we can assume that it's not a valid image 
      //------------------------------------------- 

      try 
      { 
       using (var bitmap = new System.Drawing.Bitmap(valFichierChoisi.InputStream)) 
       { 
       } 
      } 
      catch (Exception) 
      { 
       return new ValidationResult(ErrorMessage); 
      } 


     } 
     return ValidationResult.Success; 

    } 

} 

我做了它的服務器端。對於客戶端驗證,僅僅因爲一個原因使用jquery unobstrusive驗證會更困難:它需要返回一個值。讓我解釋。假設這個驗證結果。

$.validator.unobtrusive.adapters.add('fichimage', ['thefile'], 
function (options) { 
    options.rules['fichimage'] = options.params; 
    if (options.message) { 
     options.messages['fichimage'] = options.message; 
    } 
    } 
); 

$.validator.addMethod('fichimage', function (value, element, params) { 
    var lechoifait = $('input[name="' + params.thefile+ '"]').val(); 

    if (value != null && value == lechoifait) { 
    //suppose that your browser allow the use of filereader 
    //know that you can obtain the selected file by using element.files[0] 
    var fr = new FileReader(); 
    fr.onloadend = function (e) { 
    //Because this is done asynchronously 
    // the return will always be true for this validation no matter the kind of file 

//apart of this, if you want to use any callback function, you will use it in this function which don't allows any return 
    }; 
fr.readAsDataURL(element.files[0]); 

     } 
    //this will always be true because of the asynchronously behaviour of onloadend function 
     return true; 

}, ''); 

這就是爲什麼我建議您實現自己的方式來解決這個
基於答案給由@Drakes(How to check file MIME type with javascript before upload?),我提出了這個答案。

假設在成功的情況下,要加載此圖像在圖像

<img id="imagetoshow" alt="" src="" style=" width :80%; height :300px; display:none; "/> 

因爲您正在使用MVC的工作,你的HTML幫助可能是類似的東西

 @Html.TextBoxFor(m => m.selectedimage, new { type = "file", @class = "someclass", onchange = "checkandshow(this)" }) 
    //this validation message is for checking for server side 
    //try another way if you are not using a model as claimed 
    @Html.ValidationMessageFor(m => m.selectedimage) 
    //you could use this label in the case of incorrect file 
     @Html.Label("", new { id = "badfile", @class = "badimageselected"}) 

在選擇圖像的情況下(我只檢查jpeg),將執行checkandshow(this)函數。爲他人類型的文件的簽名,請參閱本(https://en.wikipedia.org/wiki/List_of_file_signatures)和/或本(https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern

function checkandshow(input) { 
//imagetoshow is the id of the image tag where you want to load your image in the case of success 
    $('#imagetoshow').attr('src', ''); 
    //you first check if the element contains any file 
if (input.files && input.files[0]) { 
    // you check if the browser support filereader 
    if (window.FileReader && window.Blob) { 
    //because the browser support this, you create an object of this class 
     var filerdr = new FileReader(); 
     filerdr.onload = function (e) { 
    //this subarray will allows you to check the first 4 bytes of the image 
      var arr = (new Uint8Array(e.target.result)).subarray(0, 4); 
      var header = ""; 
      for (var i = 0; i < arr.length; i++) { 
       header += arr[i].toString(16); 
      } 
    //typeFichier function will allows you obtaining the real mime of the file 
      var letype = typeFichier(header); 
      if (letype != 'image/jpeg') { 
    //in the case that it is not you type of file, just do whatever you want 
    //set the text in the label to prevent the user of this bad file 
    $("#badfile").text('The selected file is not a jpeg or jpg file.'); 
      } 
      else { 
    //in the case of the good real MIME, you remove the text in the label and then load your image to the corresponding place 
       $("#badfile").text(''); 
       //you just load the correct image 
       var loaderfr = new FileReader(); 
       loaderfr.onload = function (c) { 
     //because the image is just show when you select the file, you change display: none and allow it be seen 
        $("#imagetoshow").show() 
        $('#imagetoshow').attr('src', c.target.result); 
       } 
     //this is for loading the image 
       loaderfr.readAsDataURL(input.files[0]); 
      } 
     } 
    //this is for loading the array buffer which will allows the bytes of the file to be checked 
     filerdr.readAsArrayBuffer(input.files[0]); 

    } else { 
     //in the case that File and Blob are not supported 
      $("#imagetoshow").show() 
     //you change the height because you want to reduce the space 
     $('#imagetoshow').height(15); 
     $('#imagetoshow').attr('alt', 'Sorry, your browser do not allows a preview of the selected image, migrate to another version of the browser or to other browser which allows this preview.'); 
    } 


    } 
}; 

非圖像類的標籤可能是這樣的

.nonimage { color: Red;font-weight:bold ; font-size:24px; } 

這裏是函數,它允許獲得文件的真實MIME

function typeFichier(entete) { 
     switch (entete) { 
      case "ffd8ffe0": 
      case "ffd8ffe1": 
      case "ffd8ffe2": 
       type = "image/jpeg"; 
       break; 
      default: 
       type = "unknown"; 
       break; 
     } 
     return type; 
    }; 

如果您想使用模型,請不要忘記添加必需的屬性,以便檢查在服務器側e文件,像這樣

[Required(FileType="selectedimage", ErrorMessage = "It seems that your file is incorrect, please try another one.")] 
    public HttpPostedFileBase selectedimage{ get; set; } 

我強烈建議你使用模型這種驗證