2014-02-14 10 views
16

fand ich die following great thread mit einer Erklärung, wie das Hochladen von Dateien durch AJAX/JQuery mit dem neuen HTML5 Formdata APIWie gehe ich mit HTML5 Multiple File Uploads in ASP.NET MVC um?

Hier ist eine leicht aktualisierte Version des Codes, mit der neueren JQuery 1.8+ Syntax

$(':button').click(function(){ 
    var formData = new FormData($('form')[0]); 
    $.ajax({ 
     url: '/Upload', //my ASP.NET MVC method 
     type: 'POST', 
     // handle the progress report 
     xhr: function() { // Custom XMLHttpRequest 
      var myXhr = $.ajaxSettings.xhr(); 
      if(myXhr.upload){ // Check if upload property exists 
       myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // For handling the progress of the upload 
      } 
      return myXhr; 
     }, 

     // Form data 
     data: formData, 

     //Options to tell jQuery not to process data or worry about content-type. 
     cache: false, 
     contentType: false, 
     processData: false 
    }) 
    .done(function(){ 
     alert("success"); 
    }) 
    .fail(function(){ 
     alert("error"); 
    }); 
}); 

function progressHandlingFunction(e){ 
    if(e.lengthComputable){ 
     $('progress').attr({value:e.loaded,max:e.total}); 
    } 
} 
zu tun

und hier ist die Form

<form enctype="multipart/form-data"> 
    <input name="file" type="file" /> 
    <input type="button" value="Upload" /> 
</form> 
<progress></progress> 

Auf der Serverseite, wir etwas davon haben.

[HttpPost] 
public string Upload(HttpPostedFileBase file) 
{ 
    // do something with file 
    return "you uploaded a file called " + file.FileName; 
} 

Das funktioniert super. Bis Sie sich entscheiden, das Attribut "multiple" im Dateidialog zu verwenden und mehrere Dateien zu senden.

<form enctype="multipart/form-data"> 
    <input name="file" type="file" multiple="multiple" /> 
    <input type="button" value="Upload" /> 
</form> 
<progress></progress> 

Sie werden verschiedene Seiten online darauf hindeutet, folgende Lösungen

public string Upload(IEnumerable<HttpPostedFileBase> files) 
{ 
    foreach(var file in files) 
     ... 
} 

Oops finden. Funktioniert nicht

public string Upload(List<HttpPostedFileBase> files) 
{ 
    foreach(var file in files) 
     ... 
} 

Nein. Funktioniert nicht. Hat

public string Upload(IEnumerable files) 
{ 
    foreach(var file in files) 
     ... 
} 

nicht einmal kompilieren

public string Upload(HttpPostedFileBase[] files) 
{ 
    foreach(HttpPostedFileBase file in files) 
     ... 
} 

was Guess? Funktioniert nicht. Versuchen wir stattdessen, Request.Files zu bearbeiten. Gute alte zuverlässige Request.Files. Geht niemals schief.

public string Upload() 
{ 
    foreach (HttpPostedFileBase uf in Request.Files) 
     ... 
} 

Spoileralarm: Es funktioniert nicht.

Aha. Ich habs! Ich werde stattdessen über die Schlüssel in Request.Files iterieren.

public string Upload() 
{ 
    foreach(var key in Request.Files.AllKeys) 
    { 
     var file = Request.Files[key]; 
    } 
} 

Noch einmal, es funktioniert nicht.

Antwort

22

Was funktioniert, ist die folgende, from the blog der immer zuverlässig und behaarter dynamisch Rick Strahl

public string Upload() 
{ 
    for (int i = 0; i < Request.Files.Count; i++) 
    { 
     var file = Request.Files[i]; 
    } 
} 

Der Grund dafür ist, dass die Sammlung von Dateien zu Request.Filesalle den gleichen Namen haben bestanden, weil sie aus einem einzigen Datei-Upload-Dialog stammen.

die serverseitige Methode ist ein einzelnes Objekt mit den Dateien übergeben, und aus irgendeinem Grund Request.Files ist der einzige Weg, um es zu bekommen.

Hoffentlich jemand, den ich habe ein bisschen Kopfschmerzen gespeichert, indem Sie diesen in.

+0

Was ist mit den Dateitypen? Ich möchte dem Benutzer erlauben, Dateien vom Typ '" .jpg "," .gif "," .png "' ... hochzuladen, aber da alle Dateien denselben Namen haben, wie könnte ich den Typ einer Datei bekommen? – sohaiby

+1

Sie haben immer noch Zugriff auf den Dateinamen, aber alle * Post-Variablen *, die diese Dateien enthalten, haben denselben Namen. Sobald Sie Ihre Datei der Variablen 'file' zugewiesen haben, können Sie den Namen und die Erweiterung überprüfen und danach filtern. – roryok

0

In meinem Fall was für mich gearbeitet wurde verbindlich alle meine Dateien in ein Ansichtsmodell Feld. ViewModel wäre das Modell, das ich für mein Frontend verwende.

@using School.ViewModels 
@model UserProfileViewModel 


<form enctype="multipart/form-data"> 
<input id="username"name="username" type="text" /> 
<input name="Myfiles" type="file" multiple="multiple" /> 
<input type="button" value="Upload" /> 
</form> 

UserProfileViewModel.cs

namespace School.ViewModels 
{ 
    public class UserProfileViewModel 
    { 
     public long Username { get; set; } 

     public List<HttpPostedFileBase> Myfiles { get; set; } 
    } 
} 

UserProfilePicturesController.cs

public ActionResult Create([Bind(Include="Username,Myfilese")] UserprofileViewModel userprofileViewModel) 
{ 
    var files = userprofileViewModel.Myfiles; 
    foreach(HttpPostedFileBase file in files) 
    { 
     //do something here 
    } 
} 
Verwandte Themen