2016-08-09 108 views
0

Ich habe ein MVC-Projekt, wo ich jquery unaufdringliche Validierung rein durch Markup allein verwenden. Eine Sache, die mich nervt, ist die Überprüfungsmeldung für den falschen Dateimime-Typ. HierjQuery unaufdringliche Validierung Fehlermeldung für Dateitypen

ist ein Beispiel auf einer normale Texteingabe mit einiger Validierung ich verwende:

<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=""> 

Eingang vereinfacht. Aber das ist im Grunde, wie ich es benutze, rein mit "Daten" -Attributen.

Aber was mir entgeht, ist das Hochladen von Dateien. Ich habe die „Zusatz methods.js“ Datei hinzugefügt, und die „accept“ Attribut validiert korrekt mit entsprechender Meldung:

<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=""> 

So wie beabsichtigt erforderlich ist, zu arbeiten, und wenn ich versuche, eine Datei zu, das ist Falscher Mime-Typ blockiert die Validierung die Formularübertragung wie vorgesehen. ABER! Es zeigt nur den Namen der Eingabe in "@ Html.ValidationMessageFor" an. Ich habe keine Ahnung, welches Datenattribut der "Accept" Validierung entspricht.

Ich habe dies versucht:

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

Aber diese Nachricht ist natürlich unabhängig von der Art Fehler angezeigt.

+0

Es gibt keine. Sie müssten ein eigenes Validierungsattribut und zugehörige Skripts erstellen, um die Methoden zu 'jquery.validate' hinzuzufügen. Einen Artikel finden Sie in diesem Artikel (http://blog.2mas.xyz/creating-custom-unobtrusive-file-extension-validation-in-asp-net-mvc-3-and-jquery/). –

+0

zeigen Sie Ihr Modell Klasse – anand

+0

Es gibt kein Modell. Deshalb verwende ich ausschließlich Datenanmerkungen. Es ist ein Formular, das automatisch generiert wird, so dass es X Menge von Eingabe-Tags verschiedener Typen haben kann. Deshalb ist der einfachste Weg der Validierung mit Datenanmerkungen. Es funktioniert tatsächlich wie ein Zauber, abgesehen von einer Nachricht für das Attribut "accept" für Datei-Uploads. –

Antwort

0

Es ist keine gute Idee, das Modell bei der Entwicklung in MVC (Model View Controller) zu vermeiden. Wie die Bedeutung von MVC sagt, sollten Sie das Modell vor dem Speichern von Daten in der Datenbank mit der IsValid-Methode meist validieren. Der Rat, den ich Ihnen geben kann, ist zu vergessen, wie Sie arbeiten, weil es nicht sicher ist. Sie können Ihre Website vor XSS-Skripten und anderen Angriffstypen schützen, wenn Sie keine isvalid-Methode eines Modells verwenden. Der Hauptvorteil des Modells besteht darin, dass Sie es leicht validieren können, bevor Sie diese Daten speichern, und dass Sie diese Art von Problemen einfach lösen können, indem Sie Ihr eigenes Validierungsattribut erstellen, das diese Daten serverseitig und clientseitig prüft. Vergessen Sie die Art und Weise, wie Sie vorgehen, und versuchen Sie einfach, über die benutzerdefinierte Validierung Bescheid zu wissen. Ich kann jedoch diesen Code teilen, der den Dateityp im Server überprüft, wenn Sie ein Modell verwenden.

 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; 

    } 

} 

Ich habe es für Serverseite gemacht. Für die clientseitige Validierung ist es schwieriger, jquery unaufdringliche Validierung nur aus einem Grund zu verwenden: Es sollte ein Wert zurückgegeben werden. Lassen Sie mich erklären. Angenommen, dieses Validierungsergebnis. Diese

$.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; 

}, ''); 

ist, warum ich Sie empfehlen Ihren eigenen Weg zu implementieren diese
von @Drakes (How to check file MIME type with javascript before upload?) geben anhand der Antwort zu lösen, schlage ich vor, diese Antwort.

Nehmen wir an, im Falle des Erfolgs, Sie möchten Ihr Bild in diesem Bild laden

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

Weil Sie mit mvc arbeiten, Ihre HTML-Helfer etwas wie das

könnte
 @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"}) 

Für den Fall, dass Sie ein Bild auswählen (ich überprüfe nur für JPEG), wird die checkandshow (this) -Funktion ausgeführt.zur Unterzeichnung von anderen Arten von Dateien finden Sie in diesem (https://en.wikipedia.org/wiki/List_of_file_signatures) und/oder die (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.'); 
    } 


    } 
}; 

die Nicht-Bild-Klasse des Labels könnte so etwas wie diese

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

hier ist die A Funktion, die die bekommen die reale MIME der Datei

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

vergessen Sie nicht das gewünschte Attribut hinzufügen, wenn Sie Modell verwenden möchten, um th zu überprüfen e-Datei in Server-Seite, so etwas wie dieses

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

ich Ihnen dringend empfehlen Modell der Validierung für diese Art zu verwenden